Addshore has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/388412 )

Change subject: Wikibase: wikibase/internal-serialization: 2.7.0
......................................................................

Wikibase: wikibase/internal-serialization: 2.7.0

Bug: T175140
Change-Id: Iaa42b222df6b53ba76409c497fc6f087b7ddbac0
---
M composer.json
M composer.lock
M composer/autoload_classmap.php
M composer/autoload_files.php
M composer/autoload_psr4.php
M composer/autoload_static.php
M composer/installed.json
A wikibase/internal-serialization/COPYING
A wikibase/internal-serialization/README.md
A wikibase/internal-serialization/src/DeserializerFactory.php
A wikibase/internal-serialization/src/Deserializers/EntityDeserializer.php
A wikibase/internal-serialization/src/Deserializers/LegacyEntityDeserializer.php
A 
wikibase/internal-serialization/src/Deserializers/LegacyEntityIdDeserializer.php
A 
wikibase/internal-serialization/src/Deserializers/LegacyFingerprintDeserializer.php
A wikibase/internal-serialization/src/Deserializers/LegacyItemDeserializer.php
A 
wikibase/internal-serialization/src/Deserializers/LegacyPropertyDeserializer.php
A 
wikibase/internal-serialization/src/Deserializers/LegacySiteLinkListDeserializer.php
A wikibase/internal-serialization/src/Deserializers/LegacySnakDeserializer.php
A 
wikibase/internal-serialization/src/Deserializers/LegacySnakListDeserializer.php
A 
wikibase/internal-serialization/src/Deserializers/LegacyStatementDeserializer.php
A wikibase/internal-serialization/src/Deserializers/StatementDeserializer.php
A wikibase/internal-serialization/src/LegacyDeserializerFactory.php
A wikibase/internal-serialization/src/SerializerFactory.php
23 files changed, 1,984 insertions(+), 7 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/vendor 
refs/changes/12/388412/1

diff --git a/composer.json b/composer.json
index 67740a0..9b6889f 100644
--- a/composer.json
+++ b/composer.json
@@ -106,6 +106,7 @@
                "symfony/var-dumper": "3.3.4",
                "wikibase/data-model": "7.2.0",
                "wikibase/data-model-serialization": "2.6.0",
+               "wikibase/internal-serialization": "2.7.0",
                "wikimedia/assert": "0.2.2",
                "wikimedia/avro": "1.7.7",
                "wikimedia/base-convert": "1.0.1",
diff --git a/composer.lock b/composer.lock
index 5e475c8..25220a8 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at 
https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file";,
         "This file is @generated automatically"
     ],
-    "content-hash": "bd9b57b9097356ae718853b7792777a5",
+    "content-hash": "bd2b5f29c8ea80d8b6f11d4b9bf6f790",
     "packages": [
         {
             "name": "composer/semver",
@@ -2456,6 +2456,69 @@
             "time": "2017-09-18T08:39:03+00:00"
         },
         {
+            "name": "wikibase/internal-serialization",
+            "version": "2.7.0",
+            "source": {
+                "type": "git",
+                "url": 
"https://github.com/wmde/WikibaseInternalSerialization.git";,
+                "reference": "a1a9257221a81b1de3226be6b13178203cf680b1"
+            },
+            "dist": {
+                "type": "zip",
+                "url": 
"https://api.github.com/repos/wmde/WikibaseInternalSerialization/zipball/a1a9257221a81b1de3226be6b13178203cf680b1";,
+                "reference": "a1a9257221a81b1de3226be6b13178203cf680b1",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.5.9",
+                "serialization/serialization": "~4.0|~3.2",
+                "wikibase/data-model": "~7.0|~6.0|~5.0|~4.2",
+                "wikibase/data-model-serialization": "~2.0"
+            },
+            "require-dev": {
+                "data-values/common": ">=0.1 <0.5",
+                "data-values/geo": ">=1.0 <3.0",
+                "data-values/number": ">=0.1 <0.10",
+                "data-values/time": ">=0.1 <0.9",
+                "phpmd/phpmd": "~2.3",
+                "phpunit/phpunit": "~4.8",
+                "wikibase/wikibase-codesniffer": "^0.2.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.7.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Wikibase\\InternalSerialization\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/";,
+            "license": [
+                "GPL-2.0+"
+            ],
+            "authors": [
+                {
+                    "name": "Jeroen De Dauw",
+                    "email": "jeroended...@gmail.com",
+                    "homepage": "http://jeroendedauw.com";
+                }
+            ],
+            "description": "Serializers and deserializers for the data access 
layer of Wikibase Repository",
+            "homepage": 
"https://github.com/wmde/WikibaseInternalSerialization";,
+            "keywords": [
+                "DataModel",
+                "deserializers",
+                "serialization",
+                "serializers",
+                "wikibase",
+                "wikidata"
+            ],
+            "time": "2017-10-26T12:45:36+00:00"
+        },
+        {
             "name": "wikimedia/assert",
             "version": "v0.2.2",
             "source": {
diff --git a/composer/autoload_classmap.php b/composer/autoload_classmap.php
index dd74924..457c999 100644
--- a/composer/autoload_classmap.php
+++ b/composer/autoload_classmap.php
@@ -1559,6 +1559,20 @@
     'Wikibase\\DataModel\\Term\\Term' => $vendorDir . 
'/wikibase/data-model/src/Term/Term.php',
     'Wikibase\\DataModel\\Term\\TermFallback' => $vendorDir . 
'/wikibase/data-model/src/Term/TermFallback.php',
     'Wikibase\\DataModel\\Term\\TermList' => $vendorDir . 
'/wikibase/data-model/src/Term/TermList.php',
+    'Wikibase\\InternalSerialization\\DeserializerFactory' => $vendorDir . 
'/wikibase/internal-serialization/src/DeserializerFactory.php',
+    'Wikibase\\InternalSerialization\\Deserializers\\EntityDeserializer' => 
$vendorDir . 
'/wikibase/internal-serialization/src/Deserializers/EntityDeserializer.php',
+    'Wikibase\\InternalSerialization\\Deserializers\\LegacyEntityDeserializer' 
=> $vendorDir . 
'/wikibase/internal-serialization/src/Deserializers/LegacyEntityDeserializer.php',
+    
'Wikibase\\InternalSerialization\\Deserializers\\LegacyEntityIdDeserializer' => 
$vendorDir . 
'/wikibase/internal-serialization/src/Deserializers/LegacyEntityIdDeserializer.php',
+    
'Wikibase\\InternalSerialization\\Deserializers\\LegacyFingerprintDeserializer' 
=> $vendorDir . 
'/wikibase/internal-serialization/src/Deserializers/LegacyFingerprintDeserializer.php',
+    'Wikibase\\InternalSerialization\\Deserializers\\LegacyItemDeserializer' 
=> $vendorDir . 
'/wikibase/internal-serialization/src/Deserializers/LegacyItemDeserializer.php',
+    
'Wikibase\\InternalSerialization\\Deserializers\\LegacyPropertyDeserializer' => 
$vendorDir . 
'/wikibase/internal-serialization/src/Deserializers/LegacyPropertyDeserializer.php',
+    
'Wikibase\\InternalSerialization\\Deserializers\\LegacySiteLinkListDeserializer'
 => $vendorDir . 
'/wikibase/internal-serialization/src/Deserializers/LegacySiteLinkListDeserializer.php',
+    'Wikibase\\InternalSerialization\\Deserializers\\LegacySnakDeserializer' 
=> $vendorDir . 
'/wikibase/internal-serialization/src/Deserializers/LegacySnakDeserializer.php',
+    
'Wikibase\\InternalSerialization\\Deserializers\\LegacySnakListDeserializer' => 
$vendorDir . 
'/wikibase/internal-serialization/src/Deserializers/LegacySnakListDeserializer.php',
+    
'Wikibase\\InternalSerialization\\Deserializers\\LegacyStatementDeserializer' 
=> $vendorDir . 
'/wikibase/internal-serialization/src/Deserializers/LegacyStatementDeserializer.php',
+    'Wikibase\\InternalSerialization\\Deserializers\\StatementDeserializer' => 
$vendorDir . 
'/wikibase/internal-serialization/src/Deserializers/StatementDeserializer.php',
+    'Wikibase\\InternalSerialization\\LegacyDeserializerFactory' => $vendorDir 
. '/wikibase/internal-serialization/src/LegacyDeserializerFactory.php',
+    'Wikibase\\InternalSerialization\\SerializerFactory' => $vendorDir . 
'/wikibase/internal-serialization/src/SerializerFactory.php',
     'Wikimedia\\Assert\\Assert' => $vendorDir . 
'/wikimedia/assert/src/Assert.php',
     'Wikimedia\\Assert\\AssertionException' => $vendorDir . 
'/wikimedia/assert/src/AssertionException.php',
     'Wikimedia\\Assert\\InvariantException' => $vendorDir . 
'/wikimedia/assert/src/InvariantException.php',
diff --git a/composer/autoload_files.php b/composer/autoload_files.php
index e9a9357..e8e50e6 100644
--- a/composer/autoload_files.php
+++ b/composer/autoload_files.php
@@ -8,15 +8,15 @@
 return array(
     '7cb394c3af2b1ae832979b0368e0da62' => $vendorDir . 
'/data-values/data-values/DataValues.php',
     'd1715cacc3c23b16a030645514266a76' => $vendorDir . 
'/data-values/interfaces/Interfaces.php',
-    '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . 
'/symfony/polyfill-mbstring/bootstrap.php',
     '90559502573a0d473dc66fde5c0ff7e2' => $vendorDir . 
'/data-values/common/Common.php',
-    'a24b5daa493ecb5e767c7d1592a8da36' => $vendorDir . 
'/mediawiki/at-ease/src/Functions.php',
+    '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . 
'/symfony/polyfill-mbstring/bootstrap.php',
     'f4c767faab43077fd89ff7cf99ffb4b8' => $vendorDir . 
'/serialization/serialization/Serialization.php',
-    '667aeda72477189d0494fecd327c3641' => $vendorDir . 
'/symfony/var-dumper/Resources/functions/dump.php',
+    'a24b5daa493ecb5e767c7d1592a8da36' => $vendorDir . 
'/mediawiki/at-ease/src/Functions.php',
     '908a529187e4aa80293c8aa78e1ec48d' => $vendorDir . 
'/data-values/time/Time.php',
     '5a494680c593293bd6035e42e2a6825c' => $vendorDir . 
'/data-values/geo/Geo.php',
     'c15f8000750e4e04ba559d9745044427' => $vendorDir . 
'/data-values/number/Number.php',
     'dc2c047038b9f5c71759f55f00aba99b' => $vendorDir . 
'/wikibase/data-model/WikibaseDataModel.php',
+    '667aeda72477189d0494fecd327c3641' => $vendorDir . 
'/symfony/var-dumper/Resources/functions/dump.php',
     'c3f7f0e81464740a933532e81fa26cc7' => $vendorDir . 
'/wikimedia/base-convert/src/Functions.php',
     'c50606d667a3fde2b80a955639479d3d' => $vendorDir . 
'/wikimedia/timestamp/src/defines.php',
     'd55c27a601de788b19a09b7d057d07ae' => $vendorDir . 
'/wikimedia/relpath/src/RelPath.php',
diff --git a/composer/autoload_psr4.php b/composer/autoload_psr4.php
index 5d79bc7..9b5b118 100644
--- a/composer/autoload_psr4.php
+++ b/composer/autoload_psr4.php
@@ -14,6 +14,7 @@
     'Wikimedia\\Composer\\' => array($vendorDir . 
'/wikimedia/composer-merge-plugin/src'),
     'Wikimedia\\Assert\\Test\\' => array($vendorDir . 
'/wikimedia/assert/tests/phpunit'),
     'Wikimedia\\Assert\\' => array($vendorDir . '/wikimedia/assert/src'),
+    'Wikibase\\InternalSerialization\\' => array($vendorDir . 
'/wikibase/internal-serialization/src'),
     'Wikibase\\DataModel\\' => array($vendorDir . '/wikibase/data-model/src', 
$vendorDir . '/wikibase/data-model-serialization/src'),
     'ValueValidators\\' => array($vendorDir . 
'/data-values/interfaces/src/ValueValidators'),
     'ValueParsers\\' => array($vendorDir . 
'/data-values/interfaces/src/ValueParsers', $vendorDir . 
'/data-values/common/src/ValueParsers'),
diff --git a/composer/autoload_static.php b/composer/autoload_static.php
index e7b14a9..ae3e743 100644
--- a/composer/autoload_static.php
+++ b/composer/autoload_static.php
@@ -9,15 +9,15 @@
     public static $files = array (
         '7cb394c3af2b1ae832979b0368e0da62' => __DIR__ . '/..' . 
'/data-values/data-values/DataValues.php',
         'd1715cacc3c23b16a030645514266a76' => __DIR__ . '/..' . 
'/data-values/interfaces/Interfaces.php',
-        '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . 
'/symfony/polyfill-mbstring/bootstrap.php',
         '90559502573a0d473dc66fde5c0ff7e2' => __DIR__ . '/..' . 
'/data-values/common/Common.php',
-        'a24b5daa493ecb5e767c7d1592a8da36' => __DIR__ . '/..' . 
'/mediawiki/at-ease/src/Functions.php',
+        '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . 
'/symfony/polyfill-mbstring/bootstrap.php',
         'f4c767faab43077fd89ff7cf99ffb4b8' => __DIR__ . '/..' . 
'/serialization/serialization/Serialization.php',
-        '667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . 
'/symfony/var-dumper/Resources/functions/dump.php',
+        'a24b5daa493ecb5e767c7d1592a8da36' => __DIR__ . '/..' . 
'/mediawiki/at-ease/src/Functions.php',
         '908a529187e4aa80293c8aa78e1ec48d' => __DIR__ . '/..' . 
'/data-values/time/Time.php',
         '5a494680c593293bd6035e42e2a6825c' => __DIR__ . '/..' . 
'/data-values/geo/Geo.php',
         'c15f8000750e4e04ba559d9745044427' => __DIR__ . '/..' . 
'/data-values/number/Number.php',
         'dc2c047038b9f5c71759f55f00aba99b' => __DIR__ . '/..' . 
'/wikibase/data-model/WikibaseDataModel.php',
+        '667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . 
'/symfony/var-dumper/Resources/functions/dump.php',
         'c3f7f0e81464740a933532e81fa26cc7' => __DIR__ . '/..' . 
'/wikimedia/base-convert/src/Functions.php',
         'c50606d667a3fde2b80a955639479d3d' => __DIR__ . '/..' . 
'/wikimedia/timestamp/src/defines.php',
         'd55c27a601de788b19a09b7d057d07ae' => __DIR__ . '/..' . 
'/wikimedia/relpath/src/RelPath.php',
@@ -40,6 +40,7 @@
             'Wikimedia\\Composer\\' => 19,
             'Wikimedia\\Assert\\Test\\' => 22,
             'Wikimedia\\Assert\\' => 17,
+            'Wikibase\\InternalSerialization\\' => 31,
             'Wikibase\\DataModel\\' => 19,
         ),
         'V' => 
@@ -136,6 +137,10 @@
         'Wikimedia\\Assert\\' => 
         array (
             0 => __DIR__ . '/..' . '/wikimedia/assert/src',
+        ),
+        'Wikibase\\InternalSerialization\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/wikibase/internal-serialization/src',
         ),
         'Wikibase\\DataModel\\' => 
         array (
@@ -1912,6 +1917,20 @@
         'Wikibase\\DataModel\\Term\\Term' => __DIR__ . '/..' . 
'/wikibase/data-model/src/Term/Term.php',
         'Wikibase\\DataModel\\Term\\TermFallback' => __DIR__ . '/..' . 
'/wikibase/data-model/src/Term/TermFallback.php',
         'Wikibase\\DataModel\\Term\\TermList' => __DIR__ . '/..' . 
'/wikibase/data-model/src/Term/TermList.php',
+        'Wikibase\\InternalSerialization\\DeserializerFactory' => __DIR__ . 
'/..' . '/wikibase/internal-serialization/src/DeserializerFactory.php',
+        'Wikibase\\InternalSerialization\\Deserializers\\EntityDeserializer' 
=> __DIR__ . '/..' . 
'/wikibase/internal-serialization/src/Deserializers/EntityDeserializer.php',
+        
'Wikibase\\InternalSerialization\\Deserializers\\LegacyEntityDeserializer' => 
__DIR__ . '/..' . 
'/wikibase/internal-serialization/src/Deserializers/LegacyEntityDeserializer.php',
+        
'Wikibase\\InternalSerialization\\Deserializers\\LegacyEntityIdDeserializer' => 
__DIR__ . '/..' . 
'/wikibase/internal-serialization/src/Deserializers/LegacyEntityIdDeserializer.php',
+        
'Wikibase\\InternalSerialization\\Deserializers\\LegacyFingerprintDeserializer' 
=> __DIR__ . '/..' . 
'/wikibase/internal-serialization/src/Deserializers/LegacyFingerprintDeserializer.php',
+        
'Wikibase\\InternalSerialization\\Deserializers\\LegacyItemDeserializer' => 
__DIR__ . '/..' . 
'/wikibase/internal-serialization/src/Deserializers/LegacyItemDeserializer.php',
+        
'Wikibase\\InternalSerialization\\Deserializers\\LegacyPropertyDeserializer' => 
__DIR__ . '/..' . 
'/wikibase/internal-serialization/src/Deserializers/LegacyPropertyDeserializer.php',
+        
'Wikibase\\InternalSerialization\\Deserializers\\LegacySiteLinkListDeserializer'
 => __DIR__ . '/..' . 
'/wikibase/internal-serialization/src/Deserializers/LegacySiteLinkListDeserializer.php',
+        
'Wikibase\\InternalSerialization\\Deserializers\\LegacySnakDeserializer' => 
__DIR__ . '/..' . 
'/wikibase/internal-serialization/src/Deserializers/LegacySnakDeserializer.php',
+        
'Wikibase\\InternalSerialization\\Deserializers\\LegacySnakListDeserializer' => 
__DIR__ . '/..' . 
'/wikibase/internal-serialization/src/Deserializers/LegacySnakListDeserializer.php',
+        
'Wikibase\\InternalSerialization\\Deserializers\\LegacyStatementDeserializer' 
=> __DIR__ . '/..' . 
'/wikibase/internal-serialization/src/Deserializers/LegacyStatementDeserializer.php',
+        
'Wikibase\\InternalSerialization\\Deserializers\\StatementDeserializer' => 
__DIR__ . '/..' . 
'/wikibase/internal-serialization/src/Deserializers/StatementDeserializer.php',
+        'Wikibase\\InternalSerialization\\LegacyDeserializerFactory' => 
__DIR__ . '/..' . 
'/wikibase/internal-serialization/src/LegacyDeserializerFactory.php',
+        'Wikibase\\InternalSerialization\\SerializerFactory' => __DIR__ . 
'/..' . '/wikibase/internal-serialization/src/SerializerFactory.php',
         'Wikimedia\\Assert\\Assert' => __DIR__ . '/..' . 
'/wikimedia/assert/src/Assert.php',
         'Wikimedia\\Assert\\AssertionException' => __DIR__ . '/..' . 
'/wikimedia/assert/src/AssertionException.php',
         'Wikimedia\\Assert\\InvariantException' => __DIR__ . '/..' . 
'/wikimedia/assert/src/InvariantException.php',
diff --git a/composer/installed.json b/composer/installed.json
index f705d61..7738b50 100644
--- a/composer/installed.json
+++ b/composer/installed.json
@@ -3656,5 +3656,70 @@
             "wikibase",
             "wikidata"
         ]
+    },
+    {
+        "name": "wikibase/internal-serialization",
+        "version": "2.7.0",
+        "version_normalized": "2.7.0.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/wmde/WikibaseInternalSerialization.git";,
+            "reference": "a1a9257221a81b1de3226be6b13178203cf680b1"
+        },
+        "dist": {
+            "type": "zip",
+            "url": 
"https://api.github.com/repos/wmde/WikibaseInternalSerialization/zipball/a1a9257221a81b1de3226be6b13178203cf680b1";,
+            "reference": "a1a9257221a81b1de3226be6b13178203cf680b1",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.5.9",
+            "serialization/serialization": "~4.0|~3.2",
+            "wikibase/data-model": "~7.0|~6.0|~5.0|~4.2",
+            "wikibase/data-model-serialization": "~2.0"
+        },
+        "require-dev": {
+            "data-values/common": ">=0.1 <0.5",
+            "data-values/geo": ">=1.0 <3.0",
+            "data-values/number": ">=0.1 <0.10",
+            "data-values/time": ">=0.1 <0.9",
+            "phpmd/phpmd": "~2.3",
+            "phpunit/phpunit": "~4.8",
+            "wikibase/wikibase-codesniffer": "^0.2.0"
+        },
+        "time": "2017-10-26T12:45:36+00:00",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "2.7.x-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-4": {
+                "Wikibase\\InternalSerialization\\": "src/"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/";,
+        "license": [
+            "GPL-2.0+"
+        ],
+        "authors": [
+            {
+                "name": "Jeroen De Dauw",
+                "email": "jeroended...@gmail.com",
+                "homepage": "http://jeroendedauw.com";
+            }
+        ],
+        "description": "Serializers and deserializers for the data access 
layer of Wikibase Repository",
+        "homepage": "https://github.com/wmde/WikibaseInternalSerialization";,
+        "keywords": [
+            "DataModel",
+            "deserializers",
+            "serialization",
+            "serializers",
+            "wikibase",
+            "wikidata"
+        ]
     }
 ]
diff --git a/wikibase/internal-serialization/COPYING 
b/wikibase/internal-serialization/COPYING
new file mode 100644
index 0000000..ebba08a
--- /dev/null
+++ b/wikibase/internal-serialization/COPYING
@@ -0,0 +1,347 @@
+The license text below "----" applies to all files within this distribution, 
other
+than those that are in a directory which contains files named "LICENSE" or
+"COPYING", or a subdirectory thereof. For those files, the license text 
contained in
+said file overrides any license information contained in directories of 
smaller depth.
+Alternative licenses are typically used for software that is provided by 
external
+parties, and merely packaged with this software for convenience.
+----
+
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/wikibase/internal-serialization/README.md 
b/wikibase/internal-serialization/README.md
new file mode 100644
index 0000000..54ec12f
--- /dev/null
+++ b/wikibase/internal-serialization/README.md
@@ -0,0 +1,197 @@
+# Wikibase Internal Serialization
+
+Library containing serializers and deserializers for the data access layer of 
[Wikibase](http://wikiba.se/) Repository.
+
+[![Build 
Status](https://secure.travis-ci.org/wmde/WikibaseInternalSerialization.png?branch=master)](http://travis-ci.org/wmde/WikibaseInternalSerialization)
+[![Code 
Coverage](https://scrutinizer-ci.com/g/wmde/WikibaseInternalSerialization/badges/coverage.png?s=b65f644a99b93ed3aa1a34e45efbccad798d168c)](https://scrutinizer-ci.com/g/wmde/WikibaseInternalSerialization/)
+[![Scrutinizer Quality 
Score](https://scrutinizer-ci.com/g/wmde/WikibaseInternalSerialization/badges/quality-score.png?s=1cd66e5c545917f947b4b838b7bfdeee9105843e)](https://scrutinizer-ci.com/g/wmde/WikibaseInternalSerialization/)
+[![Dependency 
Status](https://www.versioneye.com/php/wikibase:internal-serialization/badge.png)](https://www.versioneye.com/php/wikibase:internal-serialization)
+
+On [Packagist](https://packagist.org/packages/wikibase/internal-serialization):
+[![Latest Stable 
Version](https://poser.pugx.org/wikibase/internal-serialization/version.png)](https://packagist.org/packages/wikibase/internal-serialization)
+[![Download 
count](https://poser.pugx.org/wikibase/internal-serialization/d/total.png)](https://packagist.org/packages/wikibase/internal-serialization)
+
+## Installation
+
+The recommended way to use this library is via 
[Composer](http://getcomposer.org/).
+
+### Composer
+
+To add this package as a local, per-project dependency to your project, simply 
add a
+dependency on `wikibase/internal-serialization` to your project's 
`composer.json` file.
+Here is a minimal example of a `composer.json` file that just defines a 
dependency on
+version 1.x of this package:
+
+    {
+        "require": {
+            "wikibase/internal-serialization": "1.*"
+        }
+    }
+
+### Manual
+
+Get the code of this package, either via git, or some other means. Also get 
all dependencies.
+You can find a list of the dependencies in the "require" section of the 
composer.json file.
+Then take care of autoloading the classes defined in the src directory.
+
+## Library usage
+
+Construct an instance of the deserializer or serializer you need via the 
appropriate factory.
+
+```php
+use Wikibase\InternalSerialization\DeserializerFactory;
+
+$deserializerFactory = new DeserializerFactory( /* ... */ );
+$entityDeserializer = $deserializerFactory->newEntityDeserializer();
+```
+
+The use the deserialize or serialize method.
+
+```php
+$entity = $entityDeserializer->deserialize( $myEntitySerialization );
+```
+
+In case of deserialization, guarding against failures is good practice.
+So it is typically better to use the slightly more verbose try-catch approach.
+
+```php
+try {
+       $entity = $entityDeserializer->deserialize( $myEntitySerialization );
+}
+catch ( DeserializationException $ex ) {
+       // Handling of the exception
+}
+```
+
+All access to services provided by this library should happen through the
+`SerializerFactory` and `DeserializerFactory`. The rest of the code is an 
implementation
+detail which users are not allowed to know about.
+
+## Library structure
+
+The Wikibase DataModel objects can all be serialized to a generic format from 
which the objects
+can later be reconstructed. This is done via a set of `Serializers\Serializer` 
implementing objects.
+These objects turn for instance a `Claim` object into a data structure 
containing only primitive
+types and arrays. This data structure can thus be readily fed to 
`json_encode`, `serialize`, or the
+like. The process of reconstructing the objects from such a serialization is 
provided by
+objects implementing the `Deserializers\Deserializer` interface.
+
+Serializers can be obtained via an instance of `SerializerFactory` and 
deserializers can be obtained
+via an instance of `DeserializerFactory`. You are not allowed to construct 
these serializers and
+deserializers directly yourself or to have any kind of knowledge of them (ie 
type hinting). These
+objects are internal to this serialization and might change name or structure 
at any time. All you
+are allowed to know when calling `$serializerFactory->newEntitySerializer()` 
is that you get back
+an instance of `Serializers\Serializer`.
+
+The library contains deserializers that handle the legacy internal 
serialization format. Those
+can be found in `Wikibase\InternalSerialization\Deserializers`, and all start 
with the word "Legacy".
+The remaining deserializers in this namespace are not specific to any format. 
They detect the one
+that is used and forward to the appropriate deserializer. These deserializers 
can thus deal with
+serializations in the old legacy format and those in the new one.
+
+The `DeserializerFactory` only returns deserializers that can deal with both 
the legacy and the
+new format.
+
+## Tests
+
+This library comes with a set up PHPUnit tests that cover all non-trivial 
code. You can run these
+tests using the PHPUnit configuration file found in the root directory. The 
tests can also be run
+via TravisCI, as a TravisCI configuration file is also provided in the root 
directory.
+
+## Authors
+
+Wikibase Internal Serialization has been written by [Jeroen De Dauw]
+(https://www.mediawiki.org/wiki/User:Jeroen_De_Dauw), partially as [Wikimedia 
Germany]
+(https://wikimedia.de) employee for the [Wikidata 
project](https://wikidata.org/).
+
+## Release notes
+
+### 2.7.0 (2017-10-26)
+
+* Added compatibility with Serialization 4.x
+
+### 2.6.0 (2017-09-18)
+
+* Added compatibility with DataValues Common 0.4, Number 0.9, and Time 0.8
+
+### 2.5.0 (2017-08-30)
+
+* Added compatibility with DataValues Geo 2.x
+* Removed MediaWiki integration files
+* Updated minimal required PHP version from 5.3 to 5.5.9
+
+### 2.4.0 (2017-03-16)
+
+* Added compatibility with Wikibase DataModel 7.x
+
+### 2.3.0 (2016-03-14)
+
+* Added compatibility with Wikibase DataModel 6.x
+
+### 2.2.0 (2016-03-03)
+
+* `DeserializerFactory` constructor now optionally takes a 
`DispatchableDeserializer` as third argument
+
+### 2.1.0 (2016-02-18)
+
+* Added compatibility with Wikibase DataModel 5.x
+* Added compatibility with DataValues Common 0.3
+
+### 2.0.0 (2015-08-31)
+
+* Dropped dependence on Wikibase DataModel Services
+
+### 1.5.0 (2015-07-29)
+
+* Added compatibility with Wikibase DataModel 4.x
+* Removed compatibility with Wikibase DataModel 3.x
+
+### 1.4.0 (2015-06-12)
+
+* Added compatibility with DataModel 3.x
+* Deprecated `LegacyDeserializerFactory::newClaimDeserializer` in favour of 
`LegacyDeserializerFactory::newStatementDeserializer`
+* Deprecated `DeserializerFactory::newClaimDeserializer` in favour of 
`DeserializerFactory::newStatementDeserializer`
+* Added support for showing the component version when loaded via MediaWiki
+* Added PHPMD and PHPCS support
+
+### 1.3.1 (2015-01-06)
+
+* Installation together with DataValues Geo 1.x is now supported
+
+### 1.3.0 (2014-10-15)
+
+* Added compatibility with DataModel 2.x
+
+### 1.2.1 (2014-09-11)
+* Added LegacyStatementDeserializer
+* Adding normalization in LegacyItemDeserializer to handle Claims (e.g. no 
ranks),
+  on Items for more robustness with old serialization formats.
+
+### 1.2.0 (2014-09-02)
+
+* Changed used DataModel version to 1.x.
+
+### 1.1.0 (2014-06-16)
+
+* Added `DeserializerFactory::newClaimDeserializer`
+* The Deserializer for snaks now constructs `UnDeserializableValue` objects 
for invalid data values
+
+### 1.0.0 (2014-05-27)
+
+Initial release with these features:
+
+* Serializers for the main Wikibase DataModel (1.0) objects
+* Deserializers for the main Wikibase DataModel (1.0) objects
+
+## Links
+
+* [Wikibase Internal Serialization on 
Packagist](https://packagist.org/packages/wikibase/internal-serialization)
+* [Wikibase Internal Serialization on 
TravisCI](https://travis-ci.org/wmde/WikibaseInternalSerialization)
+* [Wikibase Internal Serialization on 
ScrutinizerCI](https://scrutinizer-ci.com/g/wmde/WikibaseInternalSerialization/)
+* [Wikibase Internal Serialization on 
Ohloh](https://www.ohloh.net/p/WikibaseInternalSerialization)
+
+## See also
+
+* [Wikibase DataModel](https://github.com/wmde/WikibaseDataModel)
+* [Wikibase DataModel 
Serialization](https://github.com/wmde/WikibaseDataModelSerialization) (For the 
public serialization format)
+* [Ask Serialization](https://github.com/wmde/AskSerialization)
diff --git a/wikibase/internal-serialization/src/DeserializerFactory.php 
b/wikibase/internal-serialization/src/DeserializerFactory.php
new file mode 100644
index 0000000..f773f53
--- /dev/null
+++ b/wikibase/internal-serialization/src/DeserializerFactory.php
@@ -0,0 +1,92 @@
+<?php
+
+namespace Wikibase\InternalSerialization;
+
+use Deserializers\Deserializer;
+use Deserializers\DispatchableDeserializer;
+use Wikibase\DataModel\DeserializerFactory as CurrentDeserializerFactory;
+use Wikibase\DataModel\Entity\EntityIdParser;
+use Wikibase\InternalSerialization\Deserializers\EntityDeserializer;
+use Wikibase\InternalSerialization\Deserializers\StatementDeserializer;
+
+/**
+ * Public interface of the library for constructing deserializers.
+ * Direct access to deserializers is prohibited, users are only allowed to
+ * know about this interface. Also note that the return type of the methods
+ * is "Deserializer". You are also not allowed to know which concrete
+ * implementation is returned.
+ *
+ * The returned deserializers can handle both serializations in the
+ * legacy internal format and in the new one.
+ *
+ * @since 1.0
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroended...@gmail.com >
+ */
+class DeserializerFactory {
+
+       /**
+        * @var LegacyDeserializerFactory
+        */
+       private $legacyFactory;
+
+       /**
+        * @var CurrentDeserializerFactory
+        */
+       private $currentFactory;
+
+       /**
+        * @var DispatchableDeserializer|null
+        */
+       private $currentEntityDeserializer;
+
+       /**
+        * @param Deserializer $dataValueDeserializer
+        * @param EntityIdParser $idParser
+        * @param DispatchableDeserializer|null $currentEntityDeserializer used 
instead of constructing
+        *        a new current Deserializer for entities using a current 
DeserializerFactory.
+        */
+       public function __construct(
+               Deserializer $dataValueDeserializer,
+               EntityIdParser $idParser,
+               DispatchableDeserializer $currentEntityDeserializer = null
+       ) {
+               $this->legacyFactory = new LegacyDeserializerFactory( 
$dataValueDeserializer, $idParser );
+               $this->currentFactory = new CurrentDeserializerFactory( 
$dataValueDeserializer, $idParser );
+               $this->currentEntityDeserializer = $currentEntityDeserializer;
+       }
+
+       /**
+        * @return Deserializer
+        */
+       public function newEntityDeserializer() {
+               return new EntityDeserializer(
+                       $this->legacyFactory->newEntityDeserializer(),
+                       $this->currentEntityDeserializer ?: 
$this->currentFactory->newEntityDeserializer()
+               );
+       }
+
+       /**
+        * @since 1.1
+        * @deprecated since 1.4 - use newStatementDeserializer instead
+        *
+        * @return Deserializer
+        */
+       public function newClaimDeserializer() {
+               return $this->newStatementDeserializer();
+       }
+
+       /**
+        * @since 1.4
+        *
+        * @return Deserializer
+        */
+       public function newStatementDeserializer() {
+               return new StatementDeserializer(
+                       $this->legacyFactory->newStatementDeserializer(),
+                       $this->currentFactory->newStatementDeserializer()
+               );
+       }
+
+}
diff --git 
a/wikibase/internal-serialization/src/Deserializers/EntityDeserializer.php 
b/wikibase/internal-serialization/src/Deserializers/EntityDeserializer.php
new file mode 100644
index 0000000..fc7ea5b
--- /dev/null
+++ b/wikibase/internal-serialization/src/Deserializers/EntityDeserializer.php
@@ -0,0 +1,71 @@
+<?php
+
+namespace Wikibase\InternalSerialization\Deserializers;
+
+use Deserializers\Deserializer;
+use Deserializers\DispatchableDeserializer;
+use Deserializers\Exceptions\DeserializationException;
+use Wikibase\DataModel\Entity\EntityDocument;
+
+/**
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroended...@gmail.com >
+ * @author Thiemo Mättig
+ */
+class EntityDeserializer implements Deserializer {
+
+       /**
+        * @var DispatchableDeserializer
+        */
+       private $legacyDeserializer;
+
+       /**
+        * @var DispatchableDeserializer
+        */
+       private $currentDeserializer;
+
+       public function __construct(
+               DispatchableDeserializer $legacyDeserializer,
+               DispatchableDeserializer $currentDeserializer
+       ) {
+               $this->legacyDeserializer = $legacyDeserializer;
+               $this->currentDeserializer = $currentDeserializer;
+       }
+
+       /**
+        * @param array $serialization
+        *
+        * @return EntityDocument
+        * @throws DeserializationException
+        */
+       public function deserialize( $serialization ) {
+               if ( !is_array( $serialization ) ) {
+                       throw new DeserializationException( 'Entity 
serialization must be an array' );
+               }
+
+               if ( $this->currentDeserializer->isDeserializerFor( 
$serialization ) ) {
+                       return $this->currentDeserializer->deserialize( 
$serialization );
+               } elseif ( $this->legacyDeserializer->isDeserializerFor( 
$serialization ) ) {
+                       return $this->legacyDeserializer->deserialize( 
$serialization );
+               } else {
+                       return $this->fromUnknownSerialization( $serialization 
);
+               }
+       }
+
+       private function fromUnknownSerialization( array $serialization ) {
+               try {
+                       return $this->currentDeserializer->deserialize( 
$serialization );
+               } catch ( DeserializationException $currentEx ) {
+                       try {
+                               return $this->legacyDeserializer->deserialize( 
$serialization );
+                       } catch ( DeserializationException $legacyEx ) {
+                               throw new DeserializationException(
+                                       'The provided entity serialization is 
neither legacy ('
+                                       . $legacyEx->getMessage() . ') nor 
current ('
+                                       . $currentEx->getMessage() . ')'
+                               );
+                       }
+               }
+       }
+
+}
diff --git 
a/wikibase/internal-serialization/src/Deserializers/LegacyEntityDeserializer.php
 
b/wikibase/internal-serialization/src/Deserializers/LegacyEntityDeserializer.php
new file mode 100644
index 0000000..a7032e8
--- /dev/null
+++ 
b/wikibase/internal-serialization/src/Deserializers/LegacyEntityDeserializer.php
@@ -0,0 +1,68 @@
+<?php
+
+namespace Wikibase\InternalSerialization\Deserializers;
+
+use Deserializers\Deserializer;
+use Deserializers\DispatchableDeserializer;
+use Deserializers\Exceptions\DeserializationException;
+use Wikibase\DataModel\Entity\EntityDocument;
+
+/**
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroended...@gmail.com >
+ */
+class LegacyEntityDeserializer implements DispatchableDeserializer {
+
+       /**
+        * @var Deserializer
+        */
+       private $itemDeserializer;
+
+       /**
+        * @var Deserializer
+        */
+       private $propertyDeserializer;
+
+       public function __construct( Deserializer $itemDeserializer, 
Deserializer $propertyDeserializer ) {
+               $this->itemDeserializer = $itemDeserializer;
+               $this->propertyDeserializer = $propertyDeserializer;
+       }
+
+       /**
+        * @param mixed $serialization
+        *
+        * @return EntityDocument
+        * @throws DeserializationException
+        */
+       public function deserialize( $serialization ) {
+               if ( !is_array( $serialization ) ) {
+                       throw new DeserializationException( 'Entity 
serialization must be an array' );
+               }
+
+               if ( $this->isPropertySerialization( $serialization ) ) {
+                       return $this->propertyDeserializer->deserialize( 
$serialization );
+               }
+
+               return $this->itemDeserializer->deserialize( $serialization );
+       }
+
+       private function isPropertySerialization( $serialization ) {
+               return array_key_exists( 'datatype', $serialization );
+       }
+
+       /**
+        * @see DispatchableDeserializer::isDeserializerFor
+        *
+        * @since 2.2
+        *
+        * @param mixed $serialization
+        *
+        * @return bool
+        */
+       public function isDeserializerFor( $serialization ) {
+               return is_array( $serialization )
+                       // This element is called 'id' in the current 
serialization.
+                       && array_key_exists( 'entity', $serialization );
+       }
+
+}
diff --git 
a/wikibase/internal-serialization/src/Deserializers/LegacyEntityIdDeserializer.php
 
b/wikibase/internal-serialization/src/Deserializers/LegacyEntityIdDeserializer.php
new file mode 100644
index 0000000..4af9738
--- /dev/null
+++ 
b/wikibase/internal-serialization/src/Deserializers/LegacyEntityIdDeserializer.php
@@ -0,0 +1,65 @@
+<?php
+
+namespace Wikibase\InternalSerialization\Deserializers;
+
+use Deserializers\Deserializer;
+use Deserializers\Exceptions\DeserializationException;
+use InvalidArgumentException;
+use Wikibase\DataModel\Entity\EntityId;
+use Wikibase\DataModel\LegacyIdInterpreter;
+use Wikibase\DataModel\Entity\EntityIdParser;
+use Wikibase\DataModel\Entity\EntityIdParsingException;
+
+/**
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroended...@gmail.com >
+ */
+class LegacyEntityIdDeserializer implements Deserializer {
+
+       /**
+        * @var EntityIdParser
+        */
+       private $idParser;
+
+       public function __construct( EntityIdParser $idParser ) {
+               $this->idParser = $idParser;
+       }
+
+       /**
+        * @param string|array $serialization
+        *
+        * @return EntityId
+        * @throws DeserializationException
+        */
+       public function deserialize( $serialization ) {
+               if ( is_string( $serialization ) ) {
+                       return $this->getParsedId( $serialization );
+               } elseif ( $this->isLegacyFormat( $serialization ) ) {
+                       return $this->getIdFromLegacyFormat( $serialization );
+               } else {
+                       throw new DeserializationException( 'Entity id format 
not recognized' );
+               }
+       }
+
+       private function isLegacyFormat( $serialization ) {
+               return is_array( $serialization ) && count( $serialization ) == 
2
+                       && array_key_exists( 0, $serialization ) && 
array_key_exists( 1, $serialization );
+       }
+
+       private function getParsedId( $serialization ) {
+               try {
+                       return $this->idParser->parse( $serialization );
+               } catch ( EntityIdParsingException $ex ) {
+                       throw new DeserializationException( $ex->getMessage(), 
$ex );
+               }
+       }
+
+       private function getIdFromLegacyFormat( array $serialization ) {
+               try {
+                       return LegacyIdInterpreter::newIdFromTypeAndNumber( 
$serialization[0], $serialization[1] );
+               } catch ( InvalidArgumentException $ex ) {
+                       throw new DeserializationException( $ex->getMessage(), 
$ex );
+               }
+       }
+
+}
diff --git 
a/wikibase/internal-serialization/src/Deserializers/LegacyFingerprintDeserializer.php
 
b/wikibase/internal-serialization/src/Deserializers/LegacyFingerprintDeserializer.php
new file mode 100644
index 0000000..1e411c0
--- /dev/null
+++ 
b/wikibase/internal-serialization/src/Deserializers/LegacyFingerprintDeserializer.php
@@ -0,0 +1,96 @@
+<?php
+
+namespace Wikibase\InternalSerialization\Deserializers;
+
+use Deserializers\Deserializer;
+use Deserializers\Exceptions\DeserializationException;
+use Deserializers\Exceptions\InvalidAttributeException;
+use InvalidArgumentException;
+use Wikibase\DataModel\Entity\Item;
+use Wikibase\DataModel\Term\AliasGroup;
+use Wikibase\DataModel\Term\AliasGroupList;
+use Wikibase\DataModel\Term\Fingerprint;
+use Wikibase\DataModel\Term\Term;
+use Wikibase\DataModel\Term\TermList;
+
+/**
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroended...@gmail.com >
+ * @author Bene* < benestar.wikime...@gmail.com >
+ */
+class LegacyFingerprintDeserializer implements Deserializer {
+
+       /**
+        * @param array $serialization
+        *
+        * @return Item
+        * @throws DeserializationException
+        */
+       public function deserialize( $serialization ) {
+               if ( !is_array( $serialization ) ) {
+                       throw new DeserializationException( 'Term serialization 
should be an array' );
+               }
+
+               try {
+                       return new Fingerprint(
+                               $this->getLabels( $serialization ),
+                               $this->getDescriptions( $serialization ),
+                               $this->getAliases( $serialization )
+                       );
+               } catch ( InvalidArgumentException $ex ) {
+                       throw new DeserializationException(
+                               'Could not deserialize fingerprint: ' . 
$ex->getMessage(),
+                               $ex
+                       );
+               }
+       }
+
+       private function getLabels( array $serialization ) {
+               $labels = array();
+
+               foreach ( $this->getArrayFromKey( 'label', $serialization ) as 
$langCode => $text ) {
+                       $labels[] = new Term( $langCode, $text );
+               }
+
+               return new TermList( $labels );
+       }
+
+       private function getDescriptions( array $serialization ) {
+               $descriptions = array();
+
+               foreach ( $this->getArrayFromKey( 'description', $serialization 
) as $langCode => $text ) {
+                       $descriptions[] = new Term( $langCode, $text );
+               }
+
+               return new TermList( $descriptions );
+       }
+
+       private function getAliases( array $serialization ) {
+               $descriptions = array();
+
+               foreach ( $this->getArrayFromKey( 'aliases', $serialization ) 
as $langCode => $texts ) {
+                       if ( $texts !== array() ) {
+                               $descriptions[] = new AliasGroup( $langCode, 
$texts );
+                       }
+               }
+
+               return new AliasGroupList( $descriptions );
+       }
+
+       private function getArrayFromKey( $key, array $serialization ) {
+               if ( !array_key_exists( $key, $serialization ) ) {
+                       return array();
+               }
+
+               if ( !is_array( $serialization[$key] ) ) {
+                       throw new InvalidAttributeException(
+                               $key,
+                               $serialization[$key],
+                               'The ' . $key . ' key should point to an array'
+                       );
+               }
+
+               return $serialization[$key];
+       }
+
+}
diff --git 
a/wikibase/internal-serialization/src/Deserializers/LegacyItemDeserializer.php 
b/wikibase/internal-serialization/src/Deserializers/LegacyItemDeserializer.php
new file mode 100644
index 0000000..e158d9f
--- /dev/null
+++ 
b/wikibase/internal-serialization/src/Deserializers/LegacyItemDeserializer.php
@@ -0,0 +1,173 @@
+<?php
+
+namespace Wikibase\InternalSerialization\Deserializers;
+
+use Deserializers\Deserializer;
+use Deserializers\Exceptions\DeserializationException;
+use Deserializers\Exceptions\InvalidAttributeException;
+use Wikibase\DataModel\Entity\Item;
+use Wikibase\DataModel\Entity\ItemId;
+use Wikibase\DataModel\SiteLinkList;
+use Wikibase\DataModel\Statement\Statement;
+use Wikibase\DataModel\Statement\StatementList;
+
+/**
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroended...@gmail.com >
+ * @author Katie Filbert < aude.w...@gmail.com >
+ * @author Bene* < benestar.wikime...@gmail.com >
+ */
+class LegacyItemDeserializer implements Deserializer {
+
+       /**
+        * @var Deserializer
+        */
+       private $idDeserializer;
+
+       /**
+        * @var Deserializer
+        */
+       private $siteLinkListDeserializer;
+
+       /**
+        * @var Deserializer
+        */
+       private $statementDeserializer;
+
+       /**
+        * @var Deserializer
+        */
+       private $fingerprintDeserializer;
+
+       public function __construct(
+               Deserializer $idDeserializer,
+               Deserializer $siteLinkListDeserializer,
+               Deserializer $statementDeserializer,
+               Deserializer $fingerprintDeserializer
+       ) {
+               $this->idDeserializer = $idDeserializer;
+               $this->siteLinkListDeserializer = $siteLinkListDeserializer;
+               $this->statementDeserializer = $statementDeserializer;
+               $this->fingerprintDeserializer = $fingerprintDeserializer;
+       }
+
+       /**
+        * @param array $serialization
+        *
+        * @return Item
+        * @throws DeserializationException
+        */
+       public function deserialize( $serialization ) {
+               if ( !is_array( $serialization ) ) {
+                       throw new DeserializationException( 'Item serialization 
should be an array' );
+               }
+
+               return new Item(
+                       $this->getItemId( $serialization ),
+                       $this->fingerprintDeserializer->deserialize( 
$serialization ),
+                       $this->getSiteLinkList( $serialization ),
+                       $this->getStatementList( $serialization )
+               );
+       }
+
+       /**
+        * @param array $serialization
+        *
+        * @return ItemId|null
+        */
+       private function getItemId( array $serialization ) {
+               if ( array_key_exists( 'entity', $serialization ) ) {
+                       return $this->idDeserializer->deserialize( 
$serialization['entity'] );
+               }
+
+               return null;
+       }
+
+       /**
+        * @param array $serialization
+        *
+        * @return SiteLinkList|null
+        */
+       private function getSiteLinkList( array $serialization ) {
+               if ( array_key_exists( 'links', $serialization ) ) {
+                       return $this->siteLinkListDeserializer->deserialize( 
$serialization['links'] );
+               }
+
+               return null;
+       }
+
+       /**
+        * @param array $serialization
+        *
+        * @return StatementList
+        */
+       private function getStatementList( array $serialization ) {
+               $serialization = $this->normalizeLegacyClaimKeys( 
$serialization );
+
+               $statementList = new StatementList();
+
+               foreach ( $this->getArrayFromKey( 'claims', $serialization ) as 
$claimSerialization ) {
+                       $this->assertClaimValueIsArray( $claimSerialization );
+                       $statementList->addStatement( $this->getStatement( 
$claimSerialization ) );
+               }
+
+               return $statementList;
+       }
+
+       /**
+        * @param array $claimSerialization
+        *
+        * @return Statement
+        */
+       private function getStatement( array $claimSerialization ) {
+               $statementSerialization = 
$this->normalizeStatementSerialization( $claimSerialization );
+
+               return $this->statementDeserializer->deserialize( 
$statementSerialization );
+       }
+
+       private function assertClaimValueIsArray( $value ) {
+               if ( !is_array( $value ) ) {
+                       throw new DeserializationException( 'Claim 
serialization must be an array.' );
+               }
+       }
+
+       private function normalizeLegacyClaimKeys( array $serialization ) {
+               // Compatibility with DataModel 0.2 and 0.3 ItemObjects.
+               // (statements key got renamed to claims)
+               if ( array_key_exists( 'statements', $serialization ) ) {
+                       $serialization['claims'] = $serialization['statements'];
+                       unset( $serialization['statements'] );
+               }
+
+               return $serialization;
+       }
+
+       private function normalizeStatementSerialization( array $seralization ) 
{
+               if ( !isset( $seralization['rank'] ) ) {
+                       $seralization['rank'] = Statement::RANK_NORMAL;
+               }
+
+               if ( !isset( $seralization['refs'] ) ) {
+                       $seralization['refs'] = array();
+               }
+
+               return $seralization;
+       }
+
+       private function getArrayFromKey( $key, array $serialization ) {
+               if ( !array_key_exists( $key, $serialization ) ) {
+                       return array();
+               }
+
+               if ( !is_array( $serialization[$key] ) ) {
+                       throw new InvalidAttributeException(
+                               $key,
+                               $serialization[$key],
+                               'The ' . $key . ' key should point to an array'
+                       );
+               }
+
+               return $serialization[$key];
+       }
+
+}
diff --git 
a/wikibase/internal-serialization/src/Deserializers/LegacyPropertyDeserializer.php
 
b/wikibase/internal-serialization/src/Deserializers/LegacyPropertyDeserializer.php
new file mode 100644
index 0000000..c49ae3e
--- /dev/null
+++ 
b/wikibase/internal-serialization/src/Deserializers/LegacyPropertyDeserializer.php
@@ -0,0 +1,99 @@
+<?php
+
+namespace Wikibase\InternalSerialization\Deserializers;
+
+use Deserializers\Deserializer;
+use Deserializers\Exceptions\DeserializationException;
+use Deserializers\Exceptions\InvalidAttributeException;
+use Deserializers\Exceptions\MissingAttributeException;
+use Wikibase\DataModel\Entity\Property;
+use Wikibase\DataModel\Entity\PropertyId;
+
+/**
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroended...@gmail.com >
+ * @author Bene* < benestar.wikime...@gmail.com >
+ */
+class LegacyPropertyDeserializer implements Deserializer {
+
+       /**
+        * @var Deserializer
+        */
+       private $idDeserializer;
+
+       /**
+        * @var Deserializer
+        */
+       private $fingerprintDeserializer;
+
+       public function __construct( Deserializer $idDeserializer, Deserializer 
$fingerprintDeserializer ) {
+               $this->idDeserializer = $idDeserializer;
+               $this->fingerprintDeserializer = $fingerprintDeserializer;
+       }
+
+       /**
+        * @param array $serialization
+        *
+        * @return Property
+        * @throws DeserializationException
+        */
+       public function deserialize( $serialization ) {
+               if ( !is_array( $serialization ) ) {
+                       throw new DeserializationException( 'Property 
serialization should be an array' );
+               }
+
+               return new Property(
+                       $this->getPropertyId( $serialization ),
+                       $this->fingerprintDeserializer->deserialize( 
$serialization ),
+                       $this->getDataTypeId( $serialization )
+               );
+       }
+
+       /**
+        * @param array $serialization
+        *
+        * @return PropertyId|null
+        * @throws InvalidAttributeException
+        */
+       private function getPropertyId( array $serialization ) {
+               if ( array_key_exists( 'entity', $serialization ) ) {
+                       $id = $this->idDeserializer->deserialize( 
$serialization['entity'] );
+
+                       if ( !( $id instanceof PropertyId ) ) {
+                               throw new InvalidAttributeException(
+                                       'entity',
+                                       $serialization['entity'],
+                                       'Properties should have a property id'
+                               );
+                       }
+
+                       return $id;
+               }
+
+               return null;
+       }
+
+       /**
+        * @param array $serialization
+        *
+        * @return string
+        * @throws MissingAttributeException
+        * @throws InvalidAttributeException
+        */
+       private function getDataTypeId( array $serialization ) {
+               if ( !array_key_exists( 'datatype', $serialization ) ) {
+                       throw new MissingAttributeException( 'datatype' );
+               }
+
+               if ( !is_string( $serialization['datatype'] ) ) {
+                       throw new InvalidAttributeException(
+                               'datatype',
+                               $serialization['datatype'],
+                               'The datatype key should point to a string'
+                       );
+               }
+
+               return $serialization['datatype'];
+       }
+
+}
diff --git 
a/wikibase/internal-serialization/src/Deserializers/LegacySiteLinkListDeserializer.php
 
b/wikibase/internal-serialization/src/Deserializers/LegacySiteLinkListDeserializer.php
new file mode 100644
index 0000000..54b161a
--- /dev/null
+++ 
b/wikibase/internal-serialization/src/Deserializers/LegacySiteLinkListDeserializer.php
@@ -0,0 +1,131 @@
+<?php
+
+namespace Wikibase\InternalSerialization\Deserializers;
+
+use Deserializers\Deserializer;
+use Deserializers\Exceptions\DeserializationException;
+use Deserializers\Exceptions\MissingAttributeException;
+use InvalidArgumentException;
+use Wikibase\DataModel\Entity\ItemId;
+use Wikibase\DataModel\SiteLink;
+use Wikibase\DataModel\SiteLinkList;
+
+/**
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroended...@gmail.com >
+ */
+class LegacySiteLinkListDeserializer implements Deserializer {
+
+       /**
+        * @param array $serialization
+        *
+        * @return SiteLink[]
+        * @throws DeserializationException
+        */
+       public function deserialize( $serialization ) {
+               $this->assertStructureIsValid( $serialization );
+
+               return $this->getDeserialized( $serialization );
+       }
+
+       private function assertStructureIsValid( $serialization ) {
+               if ( !is_array( $serialization ) ) {
+                       throw new DeserializationException( 'SiteLink list 
serializations should be arrays' );
+               }
+
+               foreach ( $serialization as $key => $arrayElement ) {
+                       $this->assertKeyIsValid( $key );
+                       $this->assertElementIsValid( $arrayElement );
+               }
+       }
+
+       private function assertKeyIsValid( $key ) {
+               if ( !is_string( $key ) ) {
+                       throw new DeserializationException( 'All array keys 
should be strings' );
+               }
+       }
+
+       private function assertElementIsValid( $arrayElement ) {
+               if ( !is_string( $arrayElement ) && !is_array( $arrayElement ) 
) {
+                       throw new DeserializationException( 'All array elements 
should be of type string or array' );
+               }
+
+               if ( is_array( $arrayElement ) ) {
+                       $this->assertElementIsValidArray( $arrayElement );
+               }
+       }
+
+       private function assertElementIsValidArray( array $arrayElement ) {
+               if ( !array_key_exists( 'name', $arrayElement ) ) {
+                       throw new MissingAttributeException( 'name' );
+               }
+
+               if ( !array_key_exists( 'badges', $arrayElement ) ) {
+                       throw new MissingAttributeException( 'badges' );
+               }
+       }
+
+       /**
+        * @param array $siteLinkArray
+        *
+        * @return SiteLinkList
+        */
+       private function getDeserialized( array $siteLinkArray ) {
+               $siteLinks = array();
+
+               foreach ( $siteLinkArray as $siteId => $siteLinkData ) {
+                       $siteLinks[] = $this->newSiteLinkFromSerialization( 
$siteId, $siteLinkData );
+               }
+
+               return new SiteLinkList( $siteLinks );
+       }
+
+       /**
+        * @param string $siteId
+        * @param string|array $siteLinkData
+        *
+        * @throws DeserializationException
+        * @return SiteLink
+        */
+       private function newSiteLinkFromSerialization( $siteId, $siteLinkData ) 
{
+               try {
+                       return $this->tryNewSiteLinkFromSerialization( $siteId, 
$siteLinkData );
+               } catch ( InvalidArgumentException $ex ) {
+                       throw new DeserializationException( $ex->getMessage(), 
$ex );
+               }
+       }
+
+       /**
+        * @param string $siteId
+        * @param string|array $siteLinkData
+        *
+        * @return SiteLink
+        */
+       private function tryNewSiteLinkFromSerialization( $siteId, 
$siteLinkData ) {
+               if ( is_array( $siteLinkData ) ) {
+                       $pageName = $siteLinkData['name'];
+                       $badges = $this->getDeserializedBadges( 
$siteLinkData['badges'] );
+               } else {
+                       $pageName = $siteLinkData;
+                       $badges = array();
+               }
+
+               return new SiteLink( $siteId, $pageName, $badges );
+       }
+
+       /**
+        * @param string[] $badgesSerialization
+        *
+        * @return ItemId[]
+        */
+       private function getDeserializedBadges( array $badgesSerialization ) {
+               $badges = array();
+
+               foreach ( $badgesSerialization as $badgeSerialization ) {
+                       $badges[] = new ItemId( $badgeSerialization );
+               }
+
+               return $badges;
+       }
+
+}
diff --git 
a/wikibase/internal-serialization/src/Deserializers/LegacySnakDeserializer.php 
b/wikibase/internal-serialization/src/Deserializers/LegacySnakDeserializer.php
new file mode 100644
index 0000000..5594543
--- /dev/null
+++ 
b/wikibase/internal-serialization/src/Deserializers/LegacySnakDeserializer.php
@@ -0,0 +1,108 @@
+<?php
+
+namespace Wikibase\InternalSerialization\Deserializers;
+
+use DataValues\DataValue;
+use DataValues\UnDeserializableValue;
+use Deserializers\Deserializer;
+use Deserializers\Exceptions\DeserializationException;
+use LogicException;
+use Wikibase\DataModel\Snak\PropertyNoValueSnak;
+use Wikibase\DataModel\Snak\PropertySomeValueSnak;
+use Wikibase\DataModel\Snak\PropertyValueSnak;
+use Wikibase\DataModel\Snak\Snak;
+
+/**
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroended...@gmail.com >
+ */
+class LegacySnakDeserializer implements Deserializer {
+
+       /**
+        * @var Deserializer
+        */
+       private $dataValueDeserializer;
+
+       public function __construct( Deserializer $dataValueDeserializer ) {
+               $this->dataValueDeserializer = $dataValueDeserializer;
+       }
+
+       /**
+        * @param array $serialization
+        *
+        * @return Snak
+        * @throws DeserializationException
+        * @throws LogicException
+        */
+       public function deserialize( $serialization ) {
+               $this->assertStructureIsValid( $serialization );
+
+               switch ( $serialization[0] ) {
+                       case 'novalue':
+                               return new PropertyNoValueSnak( 
$serialization[1] );
+                       case 'somevalue':
+                               return new PropertySomeValueSnak( 
$serialization[1] );
+                       case 'value':
+                               return $this->deserializeValueSnak( 
$serialization );
+                               // @codeCoverageIgnoreStart
+                       default:
+                               throw new LogicException();
+               }
+               // @codeCoverageIgnoreEnd
+       }
+
+       private function deserializeValueSnak( array $serialization ) {
+               try {
+                       $dataValue = $this->dataValueDeserializer->deserialize(
+                               array(
+                                       'type' => $serialization[2],
+                                       'value' => $serialization[3],
+                               )
+                       );
+               } catch ( DeserializationException $ex ) {
+                       $dataValue = new UnDeserializableValue( 
$serialization[3], $serialization[2], $ex->getMessage() );
+               }
+
+               /**
+                * @var DataValue $dataValue
+                */
+               return new PropertyValueSnak( $serialization[1], $dataValue );
+       }
+
+       private function assertStructureIsValid( $serialization ) {
+               if ( !is_array( $serialization ) || $serialization === array() 
) {
+                       throw new DeserializationException( 'Serialization 
should be a non-empty array' );
+               }
+
+               if ( $serialization[0] === 'value' ) {
+                       $this->assertIsValueSnak( $serialization );
+               } else {
+                       $this->assertIsNonValueSnak( $serialization );
+               }
+
+               $this->assertIsPropertyId( $serialization[1] );
+       }
+
+       private function assertIsValueSnak( array $serialization ) {
+               if ( count( $serialization ) != 4 ) {
+                       throw new DeserializationException( 'Value snaks need 
to have 4 elements' );
+               }
+       }
+
+       private function assertIsNonValueSnak( array $serialization ) {
+               if ( count( $serialization ) != 2 ) {
+                       throw new DeserializationException( 'Non-value snaks 
need to have 2 elements' );
+               }
+
+               if ( !in_array( $serialization[0], array( 'novalue', 
'somevalue' ) ) ) {
+                       throw new DeserializationException( 'Unknown snak type' 
);
+               }
+       }
+
+       private function assertIsPropertyId( $idSerialization ) {
+               if ( !is_int( $idSerialization ) || $idSerialization < 1 ) {
+                       throw new DeserializationException( 'Property id needs 
to be an int bigger than 0' );
+               }
+       }
+
+}
diff --git 
a/wikibase/internal-serialization/src/Deserializers/LegacySnakListDeserializer.php
 
b/wikibase/internal-serialization/src/Deserializers/LegacySnakListDeserializer.php
new file mode 100644
index 0000000..6cda316
--- /dev/null
+++ 
b/wikibase/internal-serialization/src/Deserializers/LegacySnakListDeserializer.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace Wikibase\InternalSerialization\Deserializers;
+
+use Deserializers\Deserializer;
+use Deserializers\Exceptions\DeserializationException;
+use Wikibase\DataModel\Snak\SnakList;
+
+/**
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroended...@gmail.com >
+ */
+class LegacySnakListDeserializer implements Deserializer {
+
+       /**
+        * @var Deserializer
+        */
+       private $snakDeserializer;
+
+       public function __construct( Deserializer $snakDeserializer ) {
+               $this->snakDeserializer = $snakDeserializer;
+       }
+
+       /**
+        * @param array $serialization
+        *
+        * @return SnakList
+        * @throws DeserializationException
+        */
+       public function deserialize( $serialization ) {
+               if ( !is_array( $serialization ) ) {
+                       throw new DeserializationException( 'SnakList 
serialization should be an array' );
+               }
+
+               $snaks = array();
+
+               foreach ( $serialization as $snakSerialization ) {
+                       $snaks[] = $this->snakDeserializer->deserialize( 
$snakSerialization );
+               }
+
+               return new SnakList( $snaks );
+       }
+
+}
diff --git 
a/wikibase/internal-serialization/src/Deserializers/LegacyStatementDeserializer.php
 
b/wikibase/internal-serialization/src/Deserializers/LegacyStatementDeserializer.php
new file mode 100644
index 0000000..10226e7
--- /dev/null
+++ 
b/wikibase/internal-serialization/src/Deserializers/LegacyStatementDeserializer.php
@@ -0,0 +1,105 @@
+<?php
+
+namespace Wikibase\InternalSerialization\Deserializers;
+
+use Deserializers\Deserializer;
+use Deserializers\DispatchableDeserializer;
+use Deserializers\Exceptions\DeserializationException;
+use Deserializers\Exceptions\MissingAttributeException;
+use InvalidArgumentException;
+use Wikibase\DataModel\Reference;
+use Wikibase\DataModel\ReferenceList;
+use Wikibase\DataModel\Statement\Statement;
+
+/**
+ * @license GPL-2.0+
+ * @author Katie Filbert < aude.w...@gmail.com >
+ * @author Jeroen De Dauw < jeroended...@gmail.com >
+ * @author Bene* < benestar.wikime...@gmail.com >
+ */
+class LegacyStatementDeserializer implements DispatchableDeserializer {
+
+       /**
+        * @var Deserializer
+        */
+       private $snakDeserializer;
+
+       /**
+        * @var Deserializer
+        */
+       private $snakListDeserializer;
+
+       public function __construct( Deserializer $snakDeserializer, 
Deserializer $snakListDeserializer ) {
+               $this->snakDeserializer = $snakDeserializer;
+               $this->snakListDeserializer = $snakListDeserializer;
+       }
+
+       /**
+        * @param array $serialization
+        *
+        * @return Statement
+        * @throws DeserializationException
+        */
+       public function deserialize( $serialization ) {
+               if ( !is_array( $serialization ) ) {
+                       throw new DeserializationException( 'Statement 
serialization must be an array' );
+               }
+
+               $this->assertHasKey( $serialization, 'm', 'Mainsnak 
serialization is missing' );
+               $this->assertHasKey( $serialization, 'q', 'Qualifiers 
serialization is missing' );
+               $this->assertHasKey( $serialization, 'g', 'Guid is missing in 
serialization' );
+               $this->assertHasKey( $serialization, 'rank', 'Rank is missing 
in serialization' );
+               $this->assertHasKey( $serialization, 'refs', 'Refs are missing 
in serialization' );
+
+               return $this->newStatement( $serialization );
+       }
+
+       private function assertHasKey( array $serialization, $key, $message ) {
+               if ( !array_key_exists( $key, $serialization ) ) {
+                       throw new MissingAttributeException( $key, $message );
+               }
+       }
+
+       private function newStatement( array $serialization ) {
+               $statement = new Statement(
+                       $this->snakDeserializer->deserialize( 
$serialization['m'] ),
+                       $this->snakListDeserializer->deserialize( 
$serialization['q'] ),
+                       $this->getReferences( $serialization['refs'] )
+               );
+
+               try {
+                       $statement->setRank( $serialization['rank'] );
+                       $statement->setGuid( $serialization['g'] );
+               } catch ( InvalidArgumentException $ex ) {
+                       throw new DeserializationException( $ex->getMessage(), 
$ex );
+               }
+
+               return $statement;
+       }
+
+       private function getReferences( array $refs ) {
+               $references = array();
+
+               foreach ( $refs as $serialization ) {
+                       $references[] = new Reference( 
$this->snakListDeserializer->deserialize( $serialization ) );
+               }
+
+               return new ReferenceList( $references );
+       }
+
+       /**
+        * @see DispatchableDeserializer::isDeserializerFor
+        *
+        * @since 2.2
+        *
+        * @param mixed $serialization
+        *
+        * @return bool
+        */
+       public function isDeserializerFor( $serialization ) {
+               return is_array( $serialization )
+                       // This element is called 'mainsnak' in the current 
serialization.
+                       && array_key_exists( 'm', $serialization );
+       }
+
+}
diff --git 
a/wikibase/internal-serialization/src/Deserializers/StatementDeserializer.php 
b/wikibase/internal-serialization/src/Deserializers/StatementDeserializer.php
new file mode 100644
index 0000000..3288102
--- /dev/null
+++ 
b/wikibase/internal-serialization/src/Deserializers/StatementDeserializer.php
@@ -0,0 +1,71 @@
+<?php
+
+namespace Wikibase\InternalSerialization\Deserializers;
+
+use Deserializers\Deserializer;
+use Deserializers\DispatchableDeserializer;
+use Deserializers\Exceptions\DeserializationException;
+use Wikibase\DataModel\Statement\Statement;
+
+/**
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroended...@gmail.com >
+ * @author Thiemo Mättig
+ */
+class StatementDeserializer implements Deserializer {
+
+       /**
+        * @var DispatchableDeserializer
+        */
+       private $legacyDeserializer;
+
+       /**
+        * @var DispatchableDeserializer
+        */
+       private $currentDeserializer;
+
+       public function __construct(
+               DispatchableDeserializer $legacyDeserializer,
+               DispatchableDeserializer $currentDeserializer
+       ) {
+               $this->legacyDeserializer = $legacyDeserializer;
+               $this->currentDeserializer = $currentDeserializer;
+       }
+
+       /**
+        * @param array $serialization
+        *
+        * @return Statement
+        * @throws DeserializationException
+        */
+       public function deserialize( $serialization ) {
+               if ( !is_array( $serialization ) ) {
+                       throw new DeserializationException( 'Claim 
serialization must be an array' );
+               }
+
+               if ( $this->currentDeserializer->isDeserializerFor( 
$serialization ) ) {
+                       return $this->currentDeserializer->deserialize( 
$serialization );
+               } elseif ( $this->legacyDeserializer->isDeserializerFor( 
$serialization ) ) {
+                       return $this->legacyDeserializer->deserialize( 
$serialization );
+               } else {
+                       return $this->fromUnknownSerialization( $serialization 
);
+               }
+       }
+
+       private function fromUnknownSerialization( array $serialization ) {
+               try {
+                       return $this->currentDeserializer->deserialize( 
$serialization );
+               } catch ( DeserializationException $currentEx ) {
+                       try {
+                               return $this->legacyDeserializer->deserialize( 
$serialization );
+                       } catch ( DeserializationException $legacyEx ) {
+                               throw new DeserializationException(
+                                       'The provided claim serialization is 
neither legacy ('
+                                       . $legacyEx->getMessage() . ') nor 
current ('
+                                       . $currentEx->getMessage() . ')'
+                               );
+                       }
+               }
+       }
+
+}
diff --git a/wikibase/internal-serialization/src/LegacyDeserializerFactory.php 
b/wikibase/internal-serialization/src/LegacyDeserializerFactory.php
new file mode 100644
index 0000000..b566152
--- /dev/null
+++ b/wikibase/internal-serialization/src/LegacyDeserializerFactory.php
@@ -0,0 +1,129 @@
+<?php
+
+namespace Wikibase\InternalSerialization;
+
+use Deserializers\Deserializer;
+use Deserializers\DispatchableDeserializer;
+use Wikibase\DataModel\Entity\EntityIdParser;
+use Wikibase\InternalSerialization\Deserializers\LegacyEntityDeserializer;
+use Wikibase\InternalSerialization\Deserializers\LegacyEntityIdDeserializer;
+use Wikibase\InternalSerialization\Deserializers\LegacyFingerprintDeserializer;
+use Wikibase\InternalSerialization\Deserializers\LegacyItemDeserializer;
+use Wikibase\InternalSerialization\Deserializers\LegacyPropertyDeserializer;
+use 
Wikibase\InternalSerialization\Deserializers\LegacySiteLinkListDeserializer;
+use Wikibase\InternalSerialization\Deserializers\LegacySnakDeserializer;
+use Wikibase\InternalSerialization\Deserializers\LegacySnakListDeserializer;
+use Wikibase\InternalSerialization\Deserializers\LegacyStatementDeserializer;
+
+/**
+ * Factory for constructing deserializers that implement handling for the 
legacy format.
+ *
+ * @since 1.0
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroended...@gmail.com >
+ */
+class LegacyDeserializerFactory {
+
+       /**
+        * @var Deserializer
+        */
+       private $dataValueDeserializer;
+
+       /**
+        * @var EntityIdParser
+        */
+       private $idParser;
+
+       public function __construct( Deserializer $dataValueDeserializer, 
EntityIdParser $idParser ) {
+               $this->dataValueDeserializer = $dataValueDeserializer;
+               $this->idParser = $idParser;
+       }
+
+       /**
+        * @return DispatchableDeserializer
+        */
+       public function newEntityDeserializer() {
+               return new LegacyEntityDeserializer(
+                       $this->newItemDeserializer(),
+                       $this->newPropertyDeserializer()
+               );
+       }
+
+       /**
+        * @return Deserializer
+        */
+       private function newItemDeserializer() {
+               return new LegacyItemDeserializer(
+                       $this->newEntityIdDeserializer(),
+                       $this->newSiteLinkListDeserializer(),
+                       $this->newStatementDeserializer(),
+                       $this->newTermsDeserializer()
+               );
+       }
+
+       /**
+        * @return Deserializer
+        */
+       private function newPropertyDeserializer() {
+               return new LegacyPropertyDeserializer(
+                       $this->newEntityIdDeserializer(),
+                       $this->newTermsDeserializer()
+               );
+       }
+
+       /**
+        * @return Deserializer
+        */
+       private function newEntityIdDeserializer() {
+               return new LegacyEntityIdDeserializer( $this->idParser );
+       }
+
+       /**
+        * @return Deserializer
+        */
+       private function newTermsDeserializer() {
+               return new LegacyFingerprintDeserializer();
+       }
+
+       /**
+        * @return Deserializer
+        */
+       private function newSiteLinkListDeserializer() {
+               return new LegacySiteLinkListDeserializer();
+       }
+
+       /**
+        * @deprecated since 1.4 - use newStatementDeserializer instead
+        *
+        * @return Deserializer
+        */
+       public function newClaimDeserializer() {
+               return $this->newStatementDeserializer();
+       }
+
+       /**
+        * @return DispatchableDeserializer
+        */
+       public function newStatementDeserializer() {
+               return new LegacyStatementDeserializer(
+                       $this->newSnakDeserializer(),
+                       $this->newSnakListDeserializer()
+               );
+       }
+
+       /**
+        * @return Deserializer
+        */
+       public function newSnakListDeserializer() {
+               return new LegacySnakListDeserializer( 
$this->newSnakDeserializer() );
+       }
+
+       /**
+        * @return Deserializer
+        */
+       public function newSnakDeserializer() {
+               return new LegacySnakDeserializer( $this->dataValueDeserializer 
);
+       }
+
+}
diff --git a/wikibase/internal-serialization/src/SerializerFactory.php 
b/wikibase/internal-serialization/src/SerializerFactory.php
new file mode 100644
index 0000000..20db691
--- /dev/null
+++ b/wikibase/internal-serialization/src/SerializerFactory.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Wikibase\InternalSerialization;
+
+/**
+ * Public interface of the library for constructing serializers.
+ * Direct access to serializers is prohibited, users are only allowed to
+ * know about this interface. Also note that the return type of the methods
+ * is "Serializer". You are also not allowed to know which concrete
+ * implementation is returned.
+ *
+ * @since 1.0
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroended...@gmail.com >
+ */
+class SerializerFactory extends \Wikibase\DataModel\SerializerFactory {
+}

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Iaa42b222df6b53ba76409c497fc6f087b7ddbac0
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/vendor
Gerrit-Branch: master
Gerrit-Owner: Addshore <addshorew...@gmail.com>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to