From 0eaa35d578509454b182e24b0bc341ff66106aec Mon Sep 17 00:00:00 2001
From: Dries <dries@buytaert.net>
Date: Wed, 19 Jun 2013 16:36:24 -0400
Subject: [PATCH] Issue #1839468 by ParisLiakos, damiankloip, dawehner, jibran:
 Replace aggregator rss parsing with Zend Feed.

---
 composer.json                                 |   3 +-
 composer.lock                                 | 160 ++-
 core/core.services.yml                        |  54 +
 core/includes/common.inc                      |   6 +
 .../Bridge/ZfExtensionManagerSfContainer.php  |  95 ++
 .../aggregator/parser/DefaultParser.php       | 366 +------
 .../aggregator/Tests/FeedParserTest.php       |   7 +
 core/vendor/autoload.php                      |   2 +-
 core/vendor/composer/ClassLoader.php          |   4 +-
 core/vendor/composer/autoload_namespaces.php  |   3 +
 core/vendor/composer/autoload_real.php        |   6 +-
 core/vendor/composer/installed.json           | 984 ++++++++++--------
 .../Symfony/Cmf/Component/Routing/.travis.yml |   1 +
 .../Cmf/Component/Routing/CHANGELOG.md        |  10 +-
 .../Cmf/Component/Routing/composer.json       |   8 +-
 .../zend-escaper/Zend/Escaper/Escaper.php     | 390 +++++++
 .../Escaper/Exception/ExceptionInterface.php  |  13 +
 .../Exception/InvalidArgumentException.php    |  18 +
 .../Escaper/Exception/RuntimeException.php    |  18 +
 .../zend-escaper/Zend/Escaper/README.md       |  15 +
 .../zend-escaper/Zend/Escaper/composer.json   |  24 +
 .../Feed/Exception/BadMethodCallException.php |  15 +
 .../Feed/Exception/ExceptionInterface.php     |  13 +
 .../Exception/InvalidArgumentException.php    |  15 +
 .../Zend/Feed/Exception/RuntimeException.php  |  15 +
 .../Feed/PubSubHubbub/AbstractCallback.php    | 291 ++++++
 .../Feed/PubSubHubbub/CallbackInterface.php   |  51 +
 .../Exception/ExceptionInterface.php          |  15 +
 .../Exception/InvalidArgumentException.php    |  17 +
 .../Exception/RuntimeException.php            |  17 +
 .../Zend/Feed/PubSubHubbub/HttpResponse.php   | 211 ++++
 .../Feed/PubSubHubbub/Model/AbstractModel.php |  39 +
 .../Feed/PubSubHubbub/Model/Subscription.php  | 142 +++
 .../SubscriptionPersistenceInterface.php      |  47 +
 .../Zend/Feed/PubSubHubbub/PubSubHubbub.php   | 147 +++
 .../Zend/Feed/PubSubHubbub/Publisher.php      | 397 +++++++
 .../Zend/Feed/PubSubHubbub/Subscriber.php     | 837 +++++++++++++++
 .../Feed/PubSubHubbub/Subscriber/Callback.php | 316 ++++++
 .../Zend/Feed/PubSubHubbub/Version.php        |  15 +
 .../zend-feed/Zend/Feed/README.md             |  15 +
 .../Zend/Feed/Reader/AbstractEntry.php        | 224 ++++
 .../Zend/Feed/Reader/AbstractFeed.php         | 300 ++++++
 .../zend-feed/Zend/Feed/Reader/Collection.php |  17 +
 .../Reader/Collection/AbstractCollection.php  |  25 +
 .../Zend/Feed/Reader/Collection/Author.php    |  29 +
 .../Zend/Feed/Reader/Collection/Category.php  |  35 +
 .../Feed/Reader/Collection/Collection.php     |  17 +
 .../Zend/Feed/Reader/Entry/AbstractEntry.php  | 230 ++++
 .../zend-feed/Zend/Feed/Reader/Entry/Atom.php | 370 +++++++
 .../Zend/Feed/Reader/Entry/EntryInterface.php | 129 +++
 .../zend-feed/Zend/Feed/Reader/Entry/Rss.php  | 599 +++++++++++
 .../Exception/BadMethodCallException.php      |  17 +
 .../Reader/Exception/ExceptionInterface.php   |  15 +
 .../Exception/InvalidArgumentException.php    |  17 +
 .../Reader/Exception/RuntimeException.php     |  17 +
 .../Feed/Reader/Extension/AbstractEntry.php   | 233 +++++
 .../Feed/Reader/Extension/AbstractFeed.php    | 176 ++++
 .../Zend/Feed/Reader/Extension/Atom/Entry.php | 628 +++++++++++
 .../Zend/Feed/Reader/Extension/Atom/Feed.php  | 536 ++++++++++
 .../Feed/Reader/Extension/Content/Entry.php   |  37 +
 .../Extension/CreativeCommons/Entry.php       |  73 ++
 .../Reader/Extension/CreativeCommons/Feed.php |  71 ++
 .../Reader/Extension/DublinCore/Entry.php     | 238 +++++
 .../Feed/Reader/Extension/DublinCore/Feed.php | 281 +++++
 .../Feed/Reader/Extension/Podcast/Entry.php   | 180 ++++
 .../Feed/Reader/Extension/Podcast/Feed.php    | 277 +++++
 .../Feed/Reader/Extension/Slash/Entry.php     | 121 +++
 .../Reader/Extension/Syndication/Feed.php     | 149 +++
 .../Feed/Reader/Extension/Thread/Entry.php    |  72 ++
 .../Reader/Extension/WellFormedWeb/Entry.php  |  50 +
 .../Zend/Feed/Reader/ExtensionManager.php     |  80 ++
 .../Feed/Reader/ExtensionManagerInterface.php |  29 +
 .../Feed/Reader/ExtensionPluginManager.php    |  77 ++
 .../Zend/Feed/Reader/Feed/AbstractFeed.php    | 307 ++++++
 .../zend-feed/Zend/Feed/Reader/Feed/Atom.php  | 410 ++++++++
 .../Zend/Feed/Reader/Feed/Atom/Source.php     |  94 ++
 .../Zend/Feed/Reader/Feed/FeedInterface.php   | 111 ++
 .../zend-feed/Zend/Feed/Reader/Feed/Rss.php   | 709 +++++++++++++
 .../zend-feed/Zend/Feed/Reader/FeedSet.php    | 127 +++
 .../Zend/Feed/Reader/Http/ClientInterface.php |  21 +
 .../Feed/Reader/Http/ResponseInterface.php    |  27 +
 .../zend-feed/Zend/Feed/Reader/Reader.php     | 674 ++++++++++++
 .../zendframework/zend-feed/Zend/Feed/Uri.php | 184 ++++
 .../Zend/Feed/Writer/AbstractFeed.php         | 848 +++++++++++++++
 .../zend-feed/Zend/Feed/Writer/Deleted.php    | 237 +++++
 .../zend-feed/Zend/Feed/Writer/Entry.php      | 767 ++++++++++++++
 .../Exception/BadMethodCallException.php      |  22 +
 .../Writer/Exception/ExceptionInterface.php   |  19 +
 .../Exception/InvalidArgumentException.php    |  22 +
 .../Writer/Exception/RuntimeException.php     |  17 +
 .../Writer/Extension/AbstractRenderer.php     | 164 +++
 .../Writer/Extension/Atom/Renderer/Feed.php   | 109 ++
 .../Extension/Content/Renderer/Entry.php      |  76 ++
 .../Extension/DublinCore/Renderer/Entry.php   |  80 ++
 .../Extension/DublinCore/Renderer/Feed.php    |  80 ++
 .../Feed/Writer/Extension/ITunes/Entry.php    | 246 +++++
 .../Feed/Writer/Extension/ITunes/Feed.php     | 362 +++++++
 .../Extension/ITunes/Renderer/Entry.php       | 200 ++++
 .../Writer/Extension/ITunes/Renderer/Feed.php | 304 ++++++
 .../Writer/Extension/RendererInterface.php    |  49 +
 .../Writer/Extension/Slash/Renderer/Entry.php |  75 ++
 .../Extension/Threading/Renderer/Entry.php    | 129 +++
 .../WellFormedWeb/Renderer/Entry.php          |  80 ++
 .../Zend/Feed/Writer/ExtensionManager.php     |  80 ++
 .../Feed/Writer/ExtensionManagerInterface.php |  29 +
 .../Feed/Writer/ExtensionPluginManager.php    |  80 ++
 .../zend-feed/Zend/Feed/Writer/Feed.php       | 241 +++++
 .../Zend/Feed/Writer/FeedFactory.php          | 127 +++
 .../Feed/Writer/Renderer/AbstractRenderer.php | 233 +++++
 .../Zend/Feed/Writer/Renderer/Entry/Atom.php  | 427 ++++++++
 .../Writer/Renderer/Entry/Atom/Deleted.php    | 102 ++
 .../Writer/Renderer/Entry/AtomDeleted.php     | 104 ++
 .../Zend/Feed/Writer/Renderer/Entry/Rss.php   | 329 ++++++
 .../Writer/Renderer/Feed/AbstractAtom.php     | 403 +++++++
 .../Zend/Feed/Writer/Renderer/Feed/Atom.php   |  96 ++
 .../Renderer/Feed/Atom/AbstractAtom.php       | 400 +++++++
 .../Feed/Writer/Renderer/Feed/Atom/Source.php |  91 ++
 .../Feed/Writer/Renderer/Feed/AtomSource.php  |  95 ++
 .../Zend/Feed/Writer/Renderer/Feed/Rss.php    | 484 +++++++++
 .../Writer/Renderer/RendererInterface.php     | 100 ++
 .../zend-feed/Zend/Feed/Writer/Source.php     |  16 +
 .../zend-feed/Zend/Feed/Writer/Version.php    |  15 +
 .../zend-feed/Zend/Feed/Writer/Writer.php     | 199 ++++
 .../zend-feed/Zend/Feed/composer.json         |  31 +
 .../Zend/Stdlib/AbstractOptions.php           | 161 +++
 .../zend-stdlib/Zend/Stdlib/ArrayObject.php   |  34 +
 .../ArrayObject/PhpLegacyCompatibility.php    |  35 +
 .../ArrayObject/PhpReferenceCompatibility.php | 433 ++++++++
 .../Stdlib/ArraySerializableInterface.php     |  28 +
 .../zend-stdlib/Zend/Stdlib/ArrayStack.php    |  33 +
 .../zend-stdlib/Zend/Stdlib/ArrayUtils.php    | 275 +++++
 .../Zend/Stdlib/CallbackHandler.php           | 218 ++++
 .../zend-stdlib/Zend/Stdlib/DateTime.php      |  47 +
 .../Zend/Stdlib/DispatchableInterface.php     |  25 +
 .../zend-stdlib/Zend/Stdlib/ErrorHandler.php  | 115 ++
 .../Exception/BadMethodCallException.php      |  17 +
 .../Zend/Stdlib/Exception/DomainException.php |  17 +
 .../Stdlib/Exception/ExceptionInterface.php   |  17 +
 .../Exception/ExtensionNotLoadedException.php |  17 +
 .../Exception/InvalidArgumentException.php    |  17 +
 .../Exception/InvalidCallbackException.php    |  17 +
 .../Zend/Stdlib/Exception/LogicException.php  |  17 +
 .../Stdlib/Exception/RuntimeException.php     |  17 +
 .../zend-stdlib/Zend/Stdlib/Glob.php          | 205 ++++
 .../Zend/Stdlib/Hydrator/AbstractHydrator.php | 198 ++++
 .../Hydrator/Aggregate/AggregateHydrator.php  |  87 ++
 .../Hydrator/Aggregate/ExtractEvent.php       |  99 ++
 .../Hydrator/Aggregate/HydrateEvent.php       |  85 ++
 .../Hydrator/Aggregate/HydratorListener.php   |  81 ++
 .../Stdlib/Hydrator/ArraySerializable.php     |  77 ++
 .../Zend/Stdlib/Hydrator/ClassMethods.php     | 190 ++++
 .../Hydrator/Filter/FilterComposite.php       | 198 ++++
 .../Hydrator/Filter/FilterInterface.php       |  21 +
 .../Filter/FilterProviderInterface.php        |  19 +
 .../Zend/Stdlib/Hydrator/Filter/GetFilter.php |  27 +
 .../Zend/Stdlib/Hydrator/Filter/HasFilter.php |  27 +
 .../Zend/Stdlib/Hydrator/Filter/IsFilter.php  |  27 +
 .../Hydrator/Filter/MethodMatchFilter.php     |  48 +
 .../Filter/NumberOfParameterFilter.php        |  54 +
 .../Hydrator/HydratorAwareInterface.php       |  28 +
 .../Stdlib/Hydrator/HydratorInterface.php     |  30 +
 .../Hydrator/HydratorOptionsInterface.php     |  19 +
 .../Stdlib/Hydrator/HydratorPluginManager.php |  56 +
 .../Zend/Stdlib/Hydrator/ObjectProperty.php   |  71 ++
 .../Zend/Stdlib/Hydrator/Reflection.php       |  92 ++
 .../Hydrator/Strategy/ClosureStrategy.php     | 100 ++
 .../Hydrator/Strategy/DefaultStrategy.php     |  35 +
 .../Strategy/SerializableStrategy.php         | 123 +++
 .../Hydrator/Strategy/StrategyInterface.php   |  29 +
 .../Hydrator/StrategyEnabledInterface.php     |  48 +
 .../Zend/Stdlib/InitializableInterface.php    |  23 +
 .../zend-stdlib/Zend/Stdlib/Message.php       | 118 +++
 .../Zend/Stdlib/MessageInterface.php          |  45 +
 .../Zend/Stdlib/ParameterObjectInterface.php  |  38 +
 .../zend-stdlib/Zend/Stdlib/Parameters.php    | 115 ++
 .../Zend/Stdlib/ParametersInterface.php       |  86 ++
 .../zend-stdlib/Zend/Stdlib/PriorityQueue.php | 302 ++++++
 .../zend-stdlib/Zend/Stdlib/README.md         |  15 +
 .../zend-stdlib/Zend/Stdlib/Request.php       |  15 +
 .../Zend/Stdlib/RequestInterface.php          |  14 +
 .../zend-stdlib/Zend/Stdlib/Response.php      |  15 +
 .../Zend/Stdlib/ResponseInterface.php         |  15 +
 .../Zend/Stdlib/SplPriorityQueue.php          |  93 ++
 .../zend-stdlib/Zend/Stdlib/SplQueue.php      |  55 +
 .../zend-stdlib/Zend/Stdlib/SplStack.php      |  55 +
 .../zend-stdlib/Zend/Stdlib/StringUtils.php   | 189 ++++
 .../StringWrapper/AbstractStringWrapper.php   | 272 +++++
 .../Zend/Stdlib/StringWrapper/Iconv.php       | 289 +++++
 .../Zend/Stdlib/StringWrapper/Intl.php        |  83 ++
 .../Zend/Stdlib/StringWrapper/MbString.php    | 121 +++
 .../Zend/Stdlib/StringWrapper/Native.php      | 134 +++
 .../StringWrapper/StringWrapperInterface.php  | 111 ++
 .../Zend/Stdlib/compatibility/autoload.php    |  14 +
 .../zend-stdlib/Zend/Stdlib/composer.json     |  28 +
 194 files changed, 25457 insertions(+), 785 deletions(-)
 create mode 100644 core/lib/Drupal/Component/Bridge/ZfExtensionManagerSfContainer.php
 create mode 100644 core/vendor/zendframework/zend-escaper/Zend/Escaper/Escaper.php
 create mode 100644 core/vendor/zendframework/zend-escaper/Zend/Escaper/Exception/ExceptionInterface.php
 create mode 100644 core/vendor/zendframework/zend-escaper/Zend/Escaper/Exception/InvalidArgumentException.php
 create mode 100644 core/vendor/zendframework/zend-escaper/Zend/Escaper/Exception/RuntimeException.php
 create mode 100644 core/vendor/zendframework/zend-escaper/Zend/Escaper/README.md
 create mode 100644 core/vendor/zendframework/zend-escaper/Zend/Escaper/composer.json
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Exception/BadMethodCallException.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Exception/ExceptionInterface.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Exception/InvalidArgumentException.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Exception/RuntimeException.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/AbstractCallback.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/CallbackInterface.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Exception/ExceptionInterface.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Exception/InvalidArgumentException.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Exception/RuntimeException.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/HttpResponse.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Model/AbstractModel.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Model/Subscription.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Model/SubscriptionPersistenceInterface.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/PubSubHubbub.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Publisher.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Subscriber.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Subscriber/Callback.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Version.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/README.md
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/AbstractEntry.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/AbstractFeed.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Collection.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Collection/AbstractCollection.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Collection/Author.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Collection/Category.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Collection/Collection.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Entry/AbstractEntry.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Entry/Atom.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Entry/EntryInterface.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Entry/Rss.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Exception/BadMethodCallException.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Exception/ExceptionInterface.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Exception/InvalidArgumentException.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Exception/RuntimeException.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/AbstractEntry.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/AbstractFeed.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Atom/Entry.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Atom/Feed.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Content/Entry.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/CreativeCommons/Entry.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/CreativeCommons/Feed.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/DublinCore/Entry.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/DublinCore/Feed.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Podcast/Entry.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Podcast/Feed.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Slash/Entry.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Syndication/Feed.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Thread/Entry.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/WellFormedWeb/Entry.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/ExtensionManager.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/ExtensionManagerInterface.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/ExtensionPluginManager.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Feed/AbstractFeed.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Feed/Atom.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Feed/Atom/Source.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Feed/FeedInterface.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Feed/Rss.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/FeedSet.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Http/ClientInterface.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Http/ResponseInterface.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Reader.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Uri.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/AbstractFeed.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Deleted.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Entry.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Exception/BadMethodCallException.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Exception/ExceptionInterface.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Exception/InvalidArgumentException.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Exception/RuntimeException.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/AbstractRenderer.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/Atom/Renderer/Feed.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/Content/Renderer/Entry.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/DublinCore/Renderer/Entry.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/DublinCore/Renderer/Feed.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/ITunes/Entry.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/ITunes/Feed.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/ITunes/Renderer/Entry.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/ITunes/Renderer/Feed.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/RendererInterface.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/Slash/Renderer/Entry.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/Threading/Renderer/Entry.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/WellFormedWeb/Renderer/Entry.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/ExtensionManager.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/ExtensionManagerInterface.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/ExtensionPluginManager.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Feed.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/FeedFactory.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/AbstractRenderer.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Entry/Atom.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Entry/Atom/Deleted.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Entry/AtomDeleted.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Entry/Rss.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Feed/AbstractAtom.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Feed/Atom.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Feed/Atom/AbstractAtom.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Feed/Atom/Source.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Feed/AtomSource.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Feed/Rss.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/RendererInterface.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Source.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Version.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Writer.php
 create mode 100644 core/vendor/zendframework/zend-feed/Zend/Feed/composer.json
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/AbstractOptions.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ArrayObject.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ArrayObject/PhpLegacyCompatibility.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ArrayObject/PhpReferenceCompatibility.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ArraySerializableInterface.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ArrayStack.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ArrayUtils.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/CallbackHandler.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/DateTime.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/DispatchableInterface.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ErrorHandler.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/BadMethodCallException.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/DomainException.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/ExceptionInterface.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/ExtensionNotLoadedException.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/InvalidArgumentException.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/InvalidCallbackException.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/LogicException.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/RuntimeException.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Glob.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/AbstractHydrator.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Aggregate/AggregateHydrator.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Aggregate/ExtractEvent.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Aggregate/HydrateEvent.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Aggregate/HydratorListener.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/ArraySerializable.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/ClassMethods.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/FilterComposite.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/FilterInterface.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/FilterProviderInterface.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/GetFilter.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/HasFilter.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/IsFilter.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/MethodMatchFilter.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/NumberOfParameterFilter.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/HydratorAwareInterface.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/HydratorInterface.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/HydratorOptionsInterface.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/HydratorPluginManager.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/ObjectProperty.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Reflection.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Strategy/ClosureStrategy.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Strategy/DefaultStrategy.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Strategy/SerializableStrategy.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Strategy/StrategyInterface.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/StrategyEnabledInterface.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/InitializableInterface.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Message.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/MessageInterface.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ParameterObjectInterface.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Parameters.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ParametersInterface.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/PriorityQueue.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/README.md
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Request.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/RequestInterface.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Response.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ResponseInterface.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/SplPriorityQueue.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/SplQueue.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/SplStack.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringUtils.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringWrapper/AbstractStringWrapper.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringWrapper/Iconv.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringWrapper/Intl.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringWrapper/MbString.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringWrapper/Native.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringWrapper/StringWrapperInterface.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/compatibility/autoload.php
 create mode 100644 core/vendor/zendframework/zend-stdlib/Zend/Stdlib/composer.json

diff --git a/composer.json b/composer.json
index f8b4473b0154..97ef123ebee2 100644
--- a/composer.json
+++ b/composer.json
@@ -19,7 +19,8 @@
     "kriswallsmith/assetic": "1.1.*@alpha",
     "symfony-cmf/routing": "1.1.*@alpha",
     "easyrdf/easyrdf": "0.8.*@beta",
-    "phpunit/phpunit": "3.7.*"
+    "phpunit/phpunit": "3.7.*",
+    "zendframework/zend-feed": "2.2.*"
   },
   "autoload": {
     "psr-0": {
diff --git a/composer.lock b/composer.lock
index dea5f2458d95..75394bafe502 100644
--- a/composer.lock
+++ b/composer.lock
@@ -3,7 +3,7 @@
         "This file locks the dependencies of your project to a known state",
         "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
     ],
-    "hash": "e2836b171e18ace7a3f758875041815a",
+    "hash": "9cad5a32fc0b4c0fac16fbda1b8ead16",
     "packages": [
         {
             "name": "doctrine/common",
@@ -791,27 +791,27 @@
         },
         {
             "name": "symfony-cmf/routing",
-            "version": "1.1.0-alpha2",
+            "version": "1.1.0-beta1",
             "target-dir": "Symfony/Cmf/Component/Routing",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony-cmf/Routing.git",
-                "reference": "1.1.0-alpha2"
+                "reference": "1.1.0-beta1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony-cmf/Routing/zipball/1.1.0-alpha2",
-                "reference": "1.1.0-alpha2",
+                "url": "https://api.github.com/repos/symfony-cmf/Routing/zipball/1.1.0-beta1",
+                "reference": "1.1.0-beta1",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.2",
+                "php": ">=5.3.3",
                 "psr/log": ">=1.0,<2.0",
-                "symfony/http-kernel": ">=2.2,<2.4-dev",
-                "symfony/routing": ">=2.2,<2.4-dev"
+                "symfony/http-kernel": ">=2.2,<3.0",
+                "symfony/routing": ">=2.2,<3.0"
             },
             "suggest": {
-                "symfony/http-foundation": "ChainRouter/DynamicRouter have optional support for Request instances, several enhancers require a Request instances, >=2.2,<2.3-dev"
+                "symfony/http-foundation": "ChainRouter/DynamicRouter have optional support for Request instances, several enhancers require a Request instances, ~2.2"
             },
             "type": "library",
             "extra": {
@@ -840,7 +840,7 @@
                 "database",
                 "routing"
             ],
-            "time": "2013-05-28 19:50:20"
+            "time": "2013-06-03 17:23:01"
         },
         {
             "name": "symfony/class-loader",
@@ -1448,17 +1448,17 @@
         },
         {
             "name": "symfony/yaml",
-            "version": "v2.3.0",
+            "version": "v2.3.1",
             "target-dir": "Symfony/Component/Yaml",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/Yaml.git",
-                "reference": "v2.3.0-RC1"
+                "reference": "v2.3.1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/Yaml/zipball/v2.3.0-RC1",
-                "reference": "v2.3.0-RC1",
+                "url": "https://api.github.com/repos/symfony/Yaml/zipball/v2.3.1",
+                "reference": "v2.3.1",
                 "shasum": ""
             },
             "require": {
@@ -1541,6 +1541,138 @@
                 "templating"
             ],
             "time": "2013-04-08 12:40:11"
+        },
+        {
+            "name": "zendframework/zend-escaper",
+            "version": "2.2.1",
+            "target-dir": "Zend/Escaper",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/zendframework/Component_ZendEscaper.git",
+                "reference": "release-2.2.1"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/zendframework/Component_ZendEscaper/zipball/release-2.2.1",
+                "reference": "release-2.2.1",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.2-dev",
+                    "dev-develop": "2.3-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Zend\\Escaper\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "keywords": [
+                "escaper",
+                "zf2"
+            ],
+            "time": "2013-05-01 21:53:03"
+        },
+        {
+            "name": "zendframework/zend-feed",
+            "version": "2.2.1",
+            "target-dir": "Zend/Feed",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/zendframework/Component_ZendFeed.git",
+                "reference": "release-2.2.1"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/zendframework/Component_ZendFeed/zipball/release-2.2.1",
+                "reference": "release-2.2.1",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3",
+                "zendframework/zend-escaper": "self.version",
+                "zendframework/zend-stdlib": "self.version"
+            },
+            "suggest": {
+                "zendframework/zend-http": "Zend\\Http for PubSubHubbub, and optionally for use with Zend\\Feed\\Reader",
+                "zendframework/zend-servicemanager": "Zend\\ServiceManager component, for default/recommended ExtensionManager implementations",
+                "zendframework/zend-validator": "Zend\\Validator component"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.2-dev",
+                    "dev-develop": "2.3-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Zend\\Feed\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "description": "provides functionality for consuming RSS and Atom feeds",
+            "keywords": [
+                "feed",
+                "zf2"
+            ],
+            "time": "2013-06-12 19:45:31"
+        },
+        {
+            "name": "zendframework/zend-stdlib",
+            "version": "2.2.1",
+            "target-dir": "Zend/Stdlib",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/zendframework/Component_ZendStdlib.git",
+                "reference": "release-2.2.1"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/zendframework/Component_ZendStdlib/zipball/release-2.2.1",
+                "reference": "release-2.2.1",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "suggest": {
+                "zendframework/zend-eventmanager": "To support aggregate hydrator usage",
+                "zendframework/zend-servicemanager": "To support hydrator plugin manager usage"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.2-dev",
+                    "dev-develop": "2.3-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Zend\\Stdlib\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "keywords": [
+                "stdlib",
+                "zf2"
+            ],
+            "time": "2013-06-12 19:46:58"
         }
     ],
     "packages-dev": [
diff --git a/core/core.services.yml b/core/core.services.yml
index 03b8c7cf0d5d..50775db7fd2a 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -465,3 +465,57 @@ services:
   date:
     class: Drupal\Core\Datetime\Date
     arguments: ['@config.factory', '@language_manager']
+  feed.bridge.reader:
+    class: Drupal\Component\Bridge\ZfExtensionManagerSfContainer
+    calls:
+      - [setContainer, ['@service_container']]
+    arguments: ['feed.reader.']
+  feed.bridge.writer:
+    class: Drupal\Component\Bridge\ZfExtensionManagerSfContainer
+    calls:
+      - [setContainer, ['@service_container']]
+    arguments: ['feed.writer.']
+# Zend Feed reader plugins
+  feed.reader.dublincoreentry:
+    class: Zend\Feed\Reader\Extension\DublinCore\Entry
+  feed.reader.dublincorefeed:
+    class: Zend\Feed\Reader\Extension\DublinCore\Feed
+  feed.reader.contententry:
+    class: Zend\Feed\Reader\Extension\Content\Entry
+  feed.reader.atomentry:
+    class: Zend\Feed\Reader\Extension\Atom\Entry
+  feed.reader.atomfeed:
+    class: Zend\Feed\Reader\Extension\Atom\Feed
+  feed.reader.slashentry:
+    class: Zend\Feed\Reader\Extension\Slash\Entry
+  feed.reader.wellformedwebentry:
+    class: Zend\Feed\Reader\Extension\WellFormedWeb\Entry
+  feed.reader.threadentry:
+    class: Zend\Feed\Reader\Extension\Thread\Entry
+  feed.reader.podcastentry:
+    class: Zend\Feed\Reader\Extension\Podcast\Entry
+  feed.reader.podcastfeed:
+    class: Zend\Feed\Reader\Extension\Podcast\Feed
+# Zend Feed writer plugins
+  feed.writer.atomrendererfeed:
+    class: Zend\Feed\Writer\Extension\Atom\Renderer\Feed
+  feed.writer.contentrendererentry:
+    class: Zend\Feed\Writer\Extension\Content\Renderer\Entry
+  feed.writer.dublincorerendererentry:
+    class: Zend\Feed\Writer\Extension\DublinCore\Renderer\Entry
+  feed.writer.dublincorerendererfeed:
+    class: Zend\Feed\Writer\Extension\DublinCore\Renderer\Feed
+  feed.writer.itunesentry:
+    class: Zend\Feed\Writer\Extension\ITunes\Entry
+  feed.writer.itunesfeed:
+    class: Zend\Feed\Writer\Extension\ITunes\Feed
+  feed.writer.itunesrendererentry:
+    class: Zend\Feed\Writer\Extension\ITunes\Renderer\Entry
+  feed.writer.itunesrendererfeed:
+    class: Zend\Feed\Writer\Extension\ITunes\Renderer\Feed
+  feed.writer.slashrendererentry:
+    class: Zend\Feed\Writer\Extension\Slash\Renderer\Entry
+  feed.writer.threadingrendererentry:
+    class: Zend\Feed\Writer\Extension\Threading\Renderer\Entry
+  feed.writer.wellformedwebrendererentry:
+    class: Zend\Feed\Writer\Extension\WellFormedWeb\Renderer\Entry
diff --git a/core/includes/common.inc b/core/includes/common.inc
index d8638feaaf6e..a392a5aa4b4f 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -22,6 +22,8 @@
 use Drupal\Core\Routing\GeneratorNotInitializedException;
 use Drupal\Core\SystemListingInfo;
 use Drupal\Core\Template\Attribute;
+use Zend\Feed\Writer\Writer;
+use Zend\Feed\Reader\Reader;
 
 /**
  * @file
@@ -3988,6 +3990,10 @@ function _drupal_bootstrap_code() {
   // Load all enabled modules
   Drupal::moduleHandler()->loadAll();
 
+  // Set our bridge extension manager to Zend Feed.
+  Reader::setExtensionManager(Drupal::service('feed.bridge.reader'));
+  Writer::setExtensionManager(Drupal::service('feed.bridge.writer'));
+
   // Make sure all stream wrappers are registered.
   file_get_stream_wrappers();
 
diff --git a/core/lib/Drupal/Component/Bridge/ZfExtensionManagerSfContainer.php b/core/lib/Drupal/Component/Bridge/ZfExtensionManagerSfContainer.php
new file mode 100644
index 000000000000..94d969b8e73c
--- /dev/null
+++ b/core/lib/Drupal/Component/Bridge/ZfExtensionManagerSfContainer.php
@@ -0,0 +1,95 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Component\Bridge\ZfExtensionManagerSfContainer
+ */
+namespace Drupal\Component\Bridge;
+
+use Symfony\Component\DependencyInjection\ContainerAwareInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Zend\Feed\Reader\ExtensionManagerInterface as ReaderManagerInterface;
+use Zend\Feed\Writer\ExtensionManagerInterface as WriterManagerInterface;
+
+/**
+ * Defines a bridge between the ZF2 service manager to Symfony container.
+ */
+class ZfExtensionManagerSfContainer implements ReaderManagerInterface, WriterManagerInterface, ContainerAwareInterface {
+
+  /**
+   * This property was based from Zend Framework (http://framework.zend.com/)
+   *
+   * @link      http://github.com/zendframework/zf2 for the canonical source repository
+   * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+   * @license   http://framework.zend.com/license/new-bsd New BSD License
+   *
+   * A map of characters to be replaced through strtr.
+   *
+   * @var array
+   *
+   * @see \Drupal\Component\Bridge\ZfExtensionManagerSfContainer::canonicalizeName().
+   */
+  protected $canonicalNamesReplacements = array('-' => '', '_' => '', ' ' => '', '\\' => '', '/' => '');
+
+  /**
+   * The prefix to be used when retrieving plugins from the container.
+   *
+   * @var string
+   */
+  protected $prefix = '';
+
+  /**
+   * Constructs a ZfExtensionManagerSfContainer object.
+   *
+   * @param string $prefix
+   *   The prefix to be used when retrieving plugins from the container.
+   */
+  public function __construct($prefix = '') {
+    return $this->prefix = $prefix;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function get($extension) {
+    return $this->container->get($this->prefix . $this->canonicalizeName($extension));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function has($extension) {
+    return $this->container->has($this->prefix . $this->canonicalizeName($extension));
+  }
+
+  /**
+   * This method was based from Zend Framework (http://framework.zend.com/)
+   *
+   * @link      http://github.com/zendframework/zf2 for the canonical source repository
+   * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+   * @license   http://framework.zend.com/license/new-bsd New BSD License
+   *
+   * Canonicalize the extension name to a service name.
+   *
+   * @param string $name
+   *   The extension name.
+   *
+   * @return string
+   *   The service name, without the prefix.
+   */
+  protected function canonicalizeName($name) {
+    if (isset($this->canonicalNames[$name])) {
+      return $this->canonicalNames[$name];
+    }
+    // This is just for performance instead of using str_replace().
+    return $this->canonicalNames[$name] = strtolower(strtr($name, $this->canonicalNamesReplacements));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setContainer(ContainerInterface $container = NULL) {
+    $this->container = $container;
+  }
+
+}
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/parser/DefaultParser.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/parser/DefaultParser.php
index eab6e9baf1e3..a295749f23e7 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/parser/DefaultParser.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/parser/DefaultParser.php
@@ -11,6 +11,9 @@
 use Drupal\aggregator\Plugin\Core\Entity\Feed;
 use Drupal\aggregator\Annotation\AggregatorParser;
 use Drupal\Core\Annotation\Translation;
+use Drupal\Core\Cache\Cache;
+use Zend\Feed\Reader\Reader;
+use Zend\Feed\Reader\Exception\ExceptionInterface;
 
 /**
  * Defines a default parser implementation.
@@ -26,353 +29,50 @@
 class DefaultParser implements ParserInterface {
 
   /**
-   * The extracted channel info.
-   *
-   * @var array
-   */
-  protected $channel = array();
-
-  /**
-   * The extracted image info.
-   *
-   * @var array
-   */
-  protected $image = array();
-
-  /**
-   * The extracted items.
-   *
-   * @var array
-   */
-  protected $items = array();
-
-  /**
-   * The element that is being processed.
-   *
-   * @var array
-   */
-  protected $element = array();
-
-  /**
-   * The tag that is being processed.
-   *
-   * @var string
-   */
-  protected $tag = '';
-
-  /**
-   * Key that holds the number of processed "entry" and "item" tags.
-   *
-   * @var int
-   */
-  protected $item;
-
-  /**
-   * Implements \Drupal\aggregator\Plugin\ParserInterface::parse().
+   * {@inheritdoc}
    */
   public function parse(Feed $feed) {
-    // Filter the input data.
-    if ($this->parseFeed($feed->source_string, $feed)) {
-
-      // Prepare the channel data.
-      foreach ($this->channel as $key => $value) {
-        $this->channel[$key] = trim($value);
-      }
-
-      // Prepare the image data (if any).
-      foreach ($this->image as $key => $value) {
-        $this->image[$key] = trim($value);
-      }
-
-      // Add parsed data to the feed object.
-      $feed->link->value = !empty($channel['link']) ? $channel['link'] : '';
-      $feed->description->value = !empty($channel['description']) ? $channel['description'] : '';
-      $feed->image->value = !empty($image['url']) ? $image['url'] : '';
-
-      // Clear the page and block caches.
-      cache_invalidate_tags(array('content' => TRUE));
-
-      return TRUE;
+    try {
+      $channel = Reader::importString($feed->source_string);
     }
+    catch (ExceptionInterface $e) {
+      watchdog_exception('aggregator', $e);
+      drupal_set_message(t('The feed from %site seems to be broken because of error "%error".', array('%site' => $feed->label(), '%error' => $e->getMessage())), 'error');
 
-    return FALSE;
-  }
-
-
-  /**
-   * Parses a feed and stores its items.
-   *
-   * @param string $data
-   *   The feed data.
-   * @param \Drupal\aggregator\Plugin\Core\Entity\Feed $feed
-   *   An object describing the feed to be parsed.
-   *
-   * @return bool
-   *   FALSE on error, TRUE otherwise.
-   */
-  protected function parseFeed(&$data, Feed $feed) {
-    // Parse the data.
-    $xml_parser = drupal_xml_parser_create($data);
-    xml_set_element_handler($xml_parser, array($this, 'elementStart'), array($this, 'elementEnd'));
-    xml_set_character_data_handler($xml_parser, array($this, 'elementData'));
-
-    if (!xml_parse($xml_parser, $data, 1)) {
-      watchdog('aggregator', 'The feed from %site seems to be broken due to an error "%error" on line %line.', array('%site' => $feed->label(), '%error' => xml_error_string(xml_get_error_code($xml_parser)), '%line' => xml_get_current_line_number($xml_parser)), WATCHDOG_WARNING);
-      drupal_set_message(t('The feed from %site seems to be broken because of error "%error" on line %line.', array('%site' => $feed->label(), '%error' => xml_error_string(xml_get_error_code($xml_parser)), '%line' => xml_get_current_line_number($xml_parser))), 'error');
       return FALSE;
     }
-    xml_parser_free($xml_parser);
-
-    // We reverse the array such that we store the first item last, and the last
-    // item first. In the database, the newest item should be at the top.
-    $this->items = array_reverse($this->items);
 
+    $feed->link->value = $channel->getLink();
+    $feed->description->value = $channel->getDescription();
+    if ($image = $channel->getImage()) {
+      $feed->image->value = $image['uri'];
+    }
     // Initialize items array.
     $feed->items = array();
-    foreach ($this->items as $item) {
-
-      // Prepare the item:
-      foreach ($item as $key => $value) {
-        $item[$key] = trim($value);
-      }
-
-      // Resolve the item's title. If no title is found, we use up to 40
-      // characters of the description ending at a word boundary, but not
-      // splitting potential entities.
-      if (!empty($item['title'])) {
-        $item['title'] = $item['title'];
-      }
-      elseif (!empty($item['description'])) {
-        $item['title'] = preg_replace('/^(.*)[^\w;&].*?$/', "\\1", truncate_utf8($item['description'], 40));
-      }
-      else {
-        $item['title'] = '';
-      }
-
-      // Resolve the items link.
-      if (!empty($item['link'])) {
-        $item['link'] = $item['link'];
+    foreach ($channel as $item) {
+      // Reset the parsed item.
+      $parsed_item = array();
+      // Move the values to an array as expected by processors.
+      $parsed_item['title'] = $item->getTitle();
+      $parsed_item['guid'] = $item->getId();
+      $parsed_item['link'] = $item->getLink();
+      $parsed_item['description'] = $item->getDescription();
+      $parsed_item['author'] = '';
+      if ($author = $item->getAuthor()) {
+        $parsed_item['author'] = $author['name'];
+      }
+      $parsed_item['timestamp'] = '';
+      if ($date = $item->getDateModified()) {
+        $parsed_item['timestamp'] = $date->getTimestamp();
       }
-      else {
-        $item['link'] = $feed->link->value;
-      }
-
-      // Atom feeds have an ID tag instead of a GUID tag.
-      if (!isset($item['guid'])) {
-        $item['guid'] = isset($item['id']) ? $item['id'] : '';
-      }
-
-      // Atom feeds have a content and/or summary tag instead of a description tag.
-      if (!empty($item['content:encoded'])) {
-        $item['description'] = $item['content:encoded'];
-      }
-      elseif (!empty($item['summary'])) {
-        $item['description'] = $item['summary'];
-      }
-      elseif (!empty($item['content'])) {
-        $item['description'] = $item['content'];
-      }
-
-      // Try to resolve and parse the item's publication date.
-      $date = '';
-      foreach (array('pubdate', 'dc:date', 'dcterms:issued', 'dcterms:created', 'dcterms:modified', 'issued', 'created', 'modified', 'published', 'updated') as $key) {
-        if (!empty($item[$key])) {
-          $date = $item[$key];
-          break;
-        }
-      }
-
-      $item['timestamp'] = strtotime($date);
-
-      if ($item['timestamp'] === FALSE) {
-        $item['timestamp'] = $this->parseW3cdtf($date); // Aggregator_parse_w3cdtf() returns FALSE on failure.
-      }
-
-      // Resolve dc:creator tag as the item author if author tag is not set.
-      if (empty($item['author']) && !empty($item['dc:creator'])) {
-        $item['author'] = $item['dc:creator'];
-      }
-
-      $item += array('author' => '', 'description' => '');
-
       // Store on $feed object. This is where processors will look for parsed items.
-      $feed->items[] = $item;
-    }
-
-    return TRUE;
-  }
-
-  /**
-   * XML parser callback: Perform an action when an opening tag is encountered.
-   *
-   * @param resource $parser
-   *   A reference to the XML parser calling the handler.
-   * @param string $name
-   *   The name of the element for which this handler is called.
-   * @param array $attributes
-   *   An associative array with the element's attributes (if any).
-   */
-  protected function elementStart($parser, $name, $attributes) {
-    $name = strtolower($name);
-    switch ($name) {
-      case 'image':
-      case 'textinput':
-      case 'summary':
-      case 'tagline':
-      case 'subtitle':
-      case 'logo':
-      case 'info':
-        $this->element = $name;
-        break;
-      case 'id':
-      case 'content':
-        if ($this->element != 'item') {
-          $this->element = $name;
-        }
-      case 'link':
-        // According to RFC 4287, link elements in Atom feeds without a 'rel'
-        // attribute should be interpreted as though the relation type is
-        // "alternate".
-        if (!empty($attributes['HREF']) && (empty($attributes['REL']) || $attributes['REL'] == 'alternate')) {
-          if ($this->element == 'item') {
-            $this->items[$this->item]['link'] = $attributes['HREF'];
-          }
-          else {
-            $this->channel['link'] = $attributes['HREF'];
-          }
-        }
-        break;
-      case 'item':
-        $this->element = $name;
-        $this->item += 1;
-        break;
-      case 'entry':
-        $this->element = 'item';
-        $this->item += 1;
-        break;
+      $feed->items[] = $parsed_item;
     }
 
-    $this->tag = $name;
-  }
-
-  /**
-   * XML parser callback: Perform an action when a closing tag is encountered.
-   *
-   * @param resource $parser
-   *   A reference to the XML parser calling the handler.
-   * @param string $name
-   *   The name of the element for which this handler is called.
-   * @param array $attributes
-   *   An associative array with the element's attributes (if any).
-   */
-  protected function elementEnd($parser, $name) {
-    switch ($name) {
-      case 'image':
-      case 'textinput':
-      case 'item':
-      case 'entry':
-      case 'info':
-        $this->element = '';
-        break;
-      case 'id':
-      case 'content':
-        if ($this->element == $name) {
-          $this->element = '';
-        }
-    }
-  }
+    // Clear the page and block caches.
+    Cache::invalidateTags(array('content' => TRUE));
 
-  /**
-   * XML parser callback: Perform an action when data is encountered.
-   *
-   * @param resource $parser
-   *   A reference to the XML parser calling the handler.
-   * @param string $name
-   *   The name of the element for which this handler is called.
-   * @param array $attributes
-   *   An associative array with the element's attributes (if any).
-   */
-  function elementData($parser, $data) {
-    $this->items += array($this->item => array());
-    switch ($this->element) {
-      case 'item':
-        $this->items[$this->item] += array($this->tag => '');
-        $this->items[$this->item][$this->tag] .= $data;
-        break;
-      case 'image':
-      case 'logo':
-        $this->image += array($this->tag => '');
-        $this->image[$this->tag] .= $data;
-        break;
-      case 'link':
-        if ($data) {
-          $this->items[$this->item] += array($tag => '');
-          $this->items[$this->item][$this->tag] .= $data;
-        }
-        break;
-      case 'content':
-        $this->items[$this->item] += array('content' => '');
-        $this->items[$this->item]['content'] .= $data;
-        break;
-      case 'summary':
-        $this->items[$this->item] += array('summary' => '');
-        $this->items[$this->item]['summary'] .= $data;
-        break;
-      case 'tagline':
-      case 'subtitle':
-        $this->channel += array('description' => '');
-        $this->channel['description'] .= $data;
-        break;
-      case 'info':
-      case 'id':
-      case 'textinput':
-        // The sub-element is not supported. However, we must recognize
-        // it or its contents will end up in the item array.
-        break;
-      default:
-        $this->channel += array($this->tag => '');
-        $this->channel[$this->tag] .= $data;
-    }
+    return TRUE;
   }
 
-  /**
-   * Parses the W3C date/time format, a subset of ISO 8601.
-   *
-   * PHP date parsing functions do not handle this format. See
-   * http://www.w3.org/TR/NOTE-datetime for more information. Originally from
-   * MagpieRSS (http://magpierss.sourceforge.net/).
-   *
-   * @param string $date_str
-   *   A string with a potentially W3C DTF date.
-   *
-   * @return int|false
-   *   A timestamp if parsed successfully or FALSE if not.
-   */
-  function parseW3cdtf($date_str) {
-    if (preg_match('/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(:(\d{2}))?(?:([-+])(\d{2}):?(\d{2})|(Z))?/', $date_str, $match)) {
-      list($year, $month, $day, $hours, $minutes, $seconds) = array($match[1], $match[2], $match[3], $match[4], $match[5], $match[6]);
-      // Calculate the epoch for current date assuming GMT.
-      $epoch = gmmktime($hours, $minutes, $seconds, $month, $day, $year);
-      if ($match[10] != 'Z') { // Z is zulu time, aka GMT
-        list($tz_mod, $tz_hour, $tz_min) = array($match[8], $match[9], $match[10]);
-        // Zero out the variables.
-        if (!$tz_hour) {
-          $tz_hour = 0;
-        }
-        if (!$tz_min) {
-          $tz_min = 0;
-        }
-        $offset_secs = (($tz_hour * 60) + $tz_min) * 60;
-        // Is timezone ahead of GMT?  If yes, subtract offset.
-        if ($tz_mod == '+') {
-          $offset_secs *= -1;
-        }
-        $epoch += $offset_secs;
-      }
-      return $epoch;
-    }
-    else {
-      return FALSE;
-    }
-  }
 }
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Tests/FeedParserTest.php b/core/modules/aggregator/lib/Drupal/aggregator/Tests/FeedParserTest.php
index 5f4f9f9c17a6..bdbe11fcc49e 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Tests/FeedParserTest.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Tests/FeedParserTest.php
@@ -7,6 +7,8 @@
 
 namespace Drupal\aggregator\Tests;
 
+use Zend\Feed\Reader\Reader;
+
 /**
  * Tests feed parsing in the Aggregator module.
  */
@@ -25,6 +27,11 @@ function setUp() {
     // feeds have hardcoded dates in them (which may be expired when this test
     // is run).
     config('aggregator.settings')->set('items.expire', AGGREGATOR_CLEAR_NEVER)->save();
+    // Reset any reader cache between tests.
+    Reader::reset();
+    // Set our bridge extension manager to Zend Feed.
+    $bridge = $this->container->get('feed.bridge.reader');
+    Reader::setExtensionManager($bridge);
   }
 
   /**
diff --git a/core/vendor/autoload.php b/core/vendor/autoload.php
index ebc5b04c3cf6..51fea2c3f72d 100644
--- a/core/vendor/autoload.php
+++ b/core/vendor/autoload.php
@@ -4,4 +4,4 @@
 
 require_once __DIR__ . '/composer' . '/autoload_real.php';
 
-return ComposerAutoloaderInitc269e792cec97d4c278bb968546f51b4::getLoader();
+return ComposerAutoloaderInit4ae4005bb4ec82f3372265feb7e84f37::getLoader();
diff --git a/core/vendor/composer/ClassLoader.php b/core/vendor/composer/ClassLoader.php
index ef9924516ae0..1db8d9a0b2e2 100644
--- a/core/vendor/composer/ClassLoader.php
+++ b/core/vendor/composer/ClassLoader.php
@@ -121,8 +121,8 @@ public function add($prefix, $paths, $prepend = false)
     /**
      * Registers a set of classes, replacing any others previously set.
      *
-     * @param string       $prefix  The classes prefix
-     * @param array|string $paths   The location(s) of the classes
+     * @param string       $prefix The classes prefix
+     * @param array|string $paths  The location(s) of the classes
      */
     public function set($prefix, $paths)
     {
diff --git a/core/vendor/composer/autoload_namespaces.php b/core/vendor/composer/autoload_namespaces.php
index 3385df1d1058..87cf5706b33e 100644
--- a/core/vendor/composer/autoload_namespaces.php
+++ b/core/vendor/composer/autoload_namespaces.php
@@ -6,6 +6,9 @@
 $baseDir = dirname(dirname($vendorDir));
 
 return array(
+    'Zend\\Stdlib\\' => array($vendorDir . '/zendframework/zend-stdlib'),
+    'Zend\\Feed\\' => array($vendorDir . '/zendframework/zend-feed'),
+    'Zend\\Escaper\\' => array($vendorDir . '/zendframework/zend-escaper'),
     'Twig_' => array($vendorDir . '/twig/twig/lib'),
     'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'),
     'Symfony\\Component\\Validator\\' => array($vendorDir . '/symfony/validator'),
diff --git a/core/vendor/composer/autoload_real.php b/core/vendor/composer/autoload_real.php
index 843e1e8c0b80..7d1d4add74e8 100644
--- a/core/vendor/composer/autoload_real.php
+++ b/core/vendor/composer/autoload_real.php
@@ -2,7 +2,7 @@
 
 // autoload_real.php generated by Composer
 
-class ComposerAutoloaderInitc269e792cec97d4c278bb968546f51b4
+class ComposerAutoloaderInit4ae4005bb4ec82f3372265feb7e84f37
 {
     private static $loader;
 
@@ -19,9 +19,9 @@ public static function getLoader()
             return self::$loader;
         }
 
-        spl_autoload_register(array('ComposerAutoloaderInitc269e792cec97d4c278bb968546f51b4', 'loadClassLoader'), true, true);
+        spl_autoload_register(array('ComposerAutoloaderInit4ae4005bb4ec82f3372265feb7e84f37', 'loadClassLoader'), true, true);
         self::$loader = $loader = new \Composer\Autoload\ClassLoader();
-        spl_autoload_unregister(array('ComposerAutoloaderInitc269e792cec97d4c278bb968546f51b4', 'loadClassLoader'));
+        spl_autoload_unregister(array('ComposerAutoloaderInit4ae4005bb4ec82f3372265feb7e84f37', 'loadClassLoader'));
 
         $vendorDir = dirname(__DIR__);
         $baseDir = dirname(dirname($vendorDir));
diff --git a/core/vendor/composer/installed.json b/core/vendor/composer/installed.json
index 7ee26800b332..322247d67963 100644
--- a/core/vendor/composer/installed.json
+++ b/core/vendor/composer/installed.json
@@ -179,109 +179,18 @@
         "homepage": "http://symfony.com"
     },
     {
-        "name": "psr/log",
-        "version": "1.0.0",
-        "version_normalized": "1.0.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/php-fig/log",
-            "reference": "1.0.0"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://github.com/php-fig/log/archive/1.0.0.zip",
-            "reference": "1.0.0",
-            "shasum": ""
-        },
-        "time": "2012-12-21 11:40:51",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-0": {
-                "Psr\\Log\\": ""
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "PHP-FIG",
-                "homepage": "http://www.php-fig.org/"
-            }
-        ],
-        "description": "Common interface for logging libraries",
-        "keywords": [
-            "log",
-            "psr",
-            "psr-3"
-        ]
-    },
-    {
-        "name": "twig/twig",
-        "version": "v1.12.3",
-        "version_normalized": "1.12.3.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/fabpot/Twig.git",
-            "reference": "v1.12.3"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/fabpot/Twig/zipball/v1.12.3",
-            "reference": "v1.12.3",
-            "shasum": ""
-        },
-        "require": {
-            "php": ">=5.2.4"
-        },
-        "time": "2013-04-08 12:40:11",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "1.12-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-0": {
-                "Twig_": "lib/"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3"
-        ],
-        "authors": [
-            {
-                "name": "Fabien Potencier",
-                "email": "fabien@symfony.com"
-            },
-            {
-                "name": "Armin Ronacher",
-                "email": "armin.ronacher@active-4.com"
-            }
-        ],
-        "description": "Twig, the flexible, fast, and secure template language for PHP",
-        "homepage": "http://twig.sensiolabs.org",
-        "keywords": [
-            "templating"
-        ]
-    },
-    {
-        "name": "symfony/debug",
+        "name": "symfony/dependency-injection",
         "version": "v2.3.1",
         "version_normalized": "2.3.1.0",
-        "target-dir": "Symfony/Component/Debug",
+        "target-dir": "Symfony/Component/DependencyInjection",
         "source": {
             "type": "git",
-            "url": "https://github.com/symfony/Debug.git",
+            "url": "https://github.com/symfony/DependencyInjection.git",
             "reference": "v2.3.1"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/symfony/Debug/zipball/v2.3.1",
+            "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/v2.3.1",
             "reference": "v2.3.1",
             "shasum": ""
         },
@@ -289,15 +198,15 @@
             "php": ">=5.3.3"
         },
         "require-dev": {
-            "symfony/http-foundation": ">=2.1,<3.0",
-            "symfony/http-kernel": ">=2.1,<3.0"
+            "symfony/config": ">=2.2,<3.0",
+            "symfony/yaml": ">=2.0,<3.0"
         },
         "suggest": {
-            "symfony/class-loader": "",
-            "symfony/http-foundation": "",
-            "symfony/http-kernel": ""
+            "symfony/config": "",
+            "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them",
+            "symfony/yaml": ""
         },
-        "time": "2013-06-02 11:58:44",
+        "time": "2013-06-05 09:51:05",
         "type": "library",
         "extra": {
             "branch-alias": {
@@ -307,7 +216,7 @@
         "installation-source": "dist",
         "autoload": {
             "psr-0": {
-                "Symfony\\Component\\Debug\\": ""
+                "Symfony\\Component\\DependencyInjection\\": ""
             }
         },
         "notification-url": "https://packagist.org/downloads/",
@@ -324,7 +233,7 @@
                 "homepage": "http://symfony.com/contributors"
             }
         ],
-        "description": "Symfony Debug Component",
+        "description": "Symfony DependencyInjection Component",
         "homepage": "http://symfony.com"
     },
     {
@@ -380,32 +289,25 @@
         "homepage": "http://symfony.com"
     },
     {
-        "name": "symfony/event-dispatcher",
-        "version": "v2.3.0",
-        "version_normalized": "2.3.0.0",
-        "target-dir": "Symfony/Component/EventDispatcher",
+        "name": "symfony/serializer",
+        "version": "v2.3.1",
+        "version_normalized": "2.3.1.0",
+        "target-dir": "Symfony/Component/Serializer",
         "source": {
             "type": "git",
-            "url": "https://github.com/symfony/EventDispatcher.git",
-            "reference": "v2.3.0-RC1"
+            "url": "https://github.com/symfony/Serializer.git",
+            "reference": "v2.3.1"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.3.0-RC1",
-            "reference": "v2.3.0-RC1",
+            "url": "https://api.github.com/repos/symfony/Serializer/zipball/v2.3.1",
+            "reference": "v2.3.1",
             "shasum": ""
         },
         "require": {
             "php": ">=5.3.3"
         },
-        "require-dev": {
-            "symfony/dependency-injection": ">=2.0,<3.0"
-        },
-        "suggest": {
-            "symfony/dependency-injection": "",
-            "symfony/http-kernel": ""
-        },
-        "time": "2013-05-13 14:36:40",
+        "time": "2013-05-10 18:12:13",
         "type": "library",
         "extra": {
             "branch-alias": {
@@ -415,7 +317,7 @@
         "installation-source": "dist",
         "autoload": {
             "psr-0": {
-                "Symfony\\Component\\EventDispatcher\\": ""
+                "Symfony\\Component\\Serializer\\": ""
             }
         },
         "notification-url": "https://packagist.org/downloads/",
@@ -432,52 +334,37 @@
                 "homepage": "http://symfony.com/contributors"
             }
         ],
-        "description": "Symfony EventDispatcher Component",
+        "description": "Symfony Serializer Component",
         "homepage": "http://symfony.com"
     },
     {
-        "name": "symfony/http-kernel",
+        "name": "symfony/translation",
         "version": "v2.3.0",
         "version_normalized": "2.3.0.0",
-        "target-dir": "Symfony/Component/HttpKernel",
+        "target-dir": "Symfony/Component/Translation",
         "source": {
             "type": "git",
-            "url": "https://github.com/symfony/HttpKernel.git",
-            "reference": "v2.3.0"
+            "url": "https://github.com/symfony/Translation.git",
+            "reference": "v2.3.0-RC1"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/v2.3.0",
-            "reference": "v2.3.0",
+            "url": "https://api.github.com/repos/symfony/Translation/zipball/v2.3.0-RC1",
+            "reference": "v2.3.0-RC1",
             "shasum": ""
         },
         "require": {
-            "php": ">=5.3.3",
-            "psr/log": ">=1.0,<2.0",
-            "symfony/debug": ">=2.3,<3.0",
-            "symfony/event-dispatcher": ">=2.1,<3.0",
-            "symfony/http-foundation": ">=2.2,<3.0"
+            "php": ">=5.3.3"
         },
         "require-dev": {
-            "symfony/browser-kit": "2.2.*",
-            "symfony/class-loader": ">=2.1,<3.0",
             "symfony/config": ">=2.0,<3.0",
-            "symfony/console": "2.2.*",
-            "symfony/dependency-injection": ">=2.0,<3.0",
-            "symfony/finder": ">=2.0,<3.0",
-            "symfony/process": ">=2.0,<3.0",
-            "symfony/routing": ">=2.2,<3.0",
-            "symfony/stopwatch": ">=2.2,<3.0"
+            "symfony/yaml": ">=2.2,<3.0"
         },
         "suggest": {
-            "symfony/browser-kit": "",
-            "symfony/class-loader": "",
             "symfony/config": "",
-            "symfony/console": "",
-            "symfony/dependency-injection": "",
-            "symfony/finder": ""
+            "symfony/yaml": ""
         },
-        "time": "2013-06-03 14:13:35",
+        "time": "2013-05-13 14:36:40",
         "type": "library",
         "extra": {
             "branch-alias": {
@@ -487,7 +374,7 @@
         "installation-source": "dist",
         "autoload": {
             "psr-0": {
-                "Symfony\\Component\\HttpKernel\\": ""
+                "Symfony\\Component\\Translation\\": ""
             }
         },
         "notification-url": "https://packagist.org/downloads/",
@@ -504,50 +391,30 @@
                 "homepage": "http://symfony.com/contributors"
             }
         ],
-        "description": "Symfony HttpKernel Component",
+        "description": "Symfony Translation Component",
         "homepage": "http://symfony.com"
     },
     {
-        "name": "symfony/routing",
-        "version": "v2.3.0",
-        "version_normalized": "2.3.0.0",
-        "target-dir": "Symfony/Component/Routing",
+        "name": "psr/log",
+        "version": "1.0.0",
+        "version_normalized": "1.0.0.0",
         "source": {
             "type": "git",
-            "url": "https://github.com/symfony/Routing.git",
-            "reference": "v2.3.0"
+            "url": "https://github.com/php-fig/log",
+            "reference": "1.0.0"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/symfony/Routing/zipball/v2.3.0",
-            "reference": "v2.3.0",
+            "url": "https://github.com/php-fig/log/archive/1.0.0.zip",
+            "reference": "1.0.0",
             "shasum": ""
         },
-        "require": {
-            "php": ">=5.3.3"
-        },
-        "require-dev": {
-            "doctrine/common": ">=2.2,<3.0",
-            "psr/log": ">=1.0,<2.0",
-            "symfony/config": ">=2.2,<3.0",
-            "symfony/yaml": ">=2.0,<3.0"
-        },
-        "suggest": {
-            "doctrine/common": "",
-            "symfony/config": "",
-            "symfony/yaml": ""
-        },
-        "time": "2013-05-20 08:57:26",
+        "time": "2012-12-21 11:40:51",
         "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "2.3-dev"
-            }
-        },
         "installation-source": "dist",
         "autoload": {
             "psr-0": {
-                "Symfony\\Component\\Routing\\": ""
+                "Psr\\Log\\": ""
             }
         },
         "notification-url": "https://packagist.org/downloads/",
@@ -556,101 +423,102 @@
         ],
         "authors": [
             {
-                "name": "Fabien Potencier",
-                "email": "fabien@symfony.com"
-            },
-            {
-                "name": "Symfony Community",
-                "homepage": "http://symfony.com/contributors"
+                "name": "PHP-FIG",
+                "homepage": "http://www.php-fig.org/"
             }
         ],
-        "description": "Symfony Routing Component",
-        "homepage": "http://symfony.com"
+        "description": "Common interface for logging libraries",
+        "keywords": [
+            "log",
+            "psr",
+            "psr-3"
+        ]
     },
     {
-        "name": "symfony-cmf/routing",
-        "version": "1.1.0-alpha2",
-        "version_normalized": "1.1.0.0-alpha2",
-        "target-dir": "Symfony/Cmf/Component/Routing",
+        "name": "twig/twig",
+        "version": "v1.12.3",
+        "version_normalized": "1.12.3.0",
         "source": {
             "type": "git",
-            "url": "https://github.com/symfony-cmf/Routing.git",
-            "reference": "1.1.0-alpha2"
+            "url": "https://github.com/fabpot/Twig.git",
+            "reference": "v1.12.3"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/symfony-cmf/Routing/zipball/1.1.0-alpha2",
-            "reference": "1.1.0-alpha2",
+            "url": "https://api.github.com/repos/fabpot/Twig/zipball/v1.12.3",
+            "reference": "v1.12.3",
             "shasum": ""
         },
         "require": {
-            "php": ">=5.3.2",
-            "psr/log": ">=1.0,<2.0",
-            "symfony/http-kernel": ">=2.2,<2.4-dev",
-            "symfony/routing": ">=2.2,<2.4-dev"
-        },
-        "suggest": {
-            "symfony/http-foundation": "ChainRouter/DynamicRouter have optional support for Request instances, several enhancers require a Request instances, >=2.2,<2.3-dev"
+            "php": ">=5.2.4"
         },
-        "time": "2013-05-28 19:50:20",
+        "time": "2013-04-08 12:40:11",
         "type": "library",
         "extra": {
             "branch-alias": {
-                "dev-master": "1.1-dev"
+                "dev-master": "1.12-dev"
             }
         },
         "installation-source": "dist",
         "autoload": {
             "psr-0": {
-                "Symfony\\Cmf\\Component\\Routing": ""
+                "Twig_": "lib/"
             }
         },
         "notification-url": "https://packagist.org/downloads/",
         "license": [
-            "MIT"
+            "BSD-3"
         ],
         "authors": [
             {
-                "name": "Symfony CMF Community",
-                "homepage": "https://github.com/symfony-cmf/Routing/contributors"
+                "name": "Fabien Potencier",
+                "email": "fabien@symfony.com"
+            },
+            {
+                "name": "Armin Ronacher",
+                "email": "armin.ronacher@active-4.com"
             }
         ],
-        "description": "Extends the Symfony2 routing component for dynamic routes and chaining several routers",
-        "homepage": "http://cmf.symfony.com",
+        "description": "Twig, the flexible, fast, and secure template language for PHP",
+        "homepage": "http://twig.sensiolabs.org",
         "keywords": [
-            "database",
-            "routing"
+            "templating"
         ]
     },
     {
-        "name": "symfony/dependency-injection",
+        "name": "symfony/validator",
         "version": "v2.3.1",
         "version_normalized": "2.3.1.0",
-        "target-dir": "Symfony/Component/DependencyInjection",
+        "target-dir": "Symfony/Component/Validator",
         "source": {
             "type": "git",
-            "url": "https://github.com/symfony/DependencyInjection.git",
+            "url": "https://github.com/symfony/Validator.git",
             "reference": "v2.3.1"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/v2.3.1",
+            "url": "https://api.github.com/repos/symfony/Validator/zipball/v2.3.1",
             "reference": "v2.3.1",
             "shasum": ""
         },
         "require": {
-            "php": ">=5.3.3"
+            "php": ">=5.3.3",
+            "symfony/translation": ">=2.0,<3.0"
         },
         "require-dev": {
             "symfony/config": ">=2.2,<3.0",
+            "symfony/http-foundation": ">=2.1,<3.0",
+            "symfony/intl": ">=2.3,<3.0",
             "symfony/yaml": ">=2.0,<3.0"
         },
         "suggest": {
+            "doctrine/common": "",
             "symfony/config": "",
-            "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them",
+            "symfony/http-foundation": "",
+            "symfony/intl": "",
             "symfony/yaml": ""
         },
-        "time": "2013-06-05 09:51:05",
+        "time": "2013-06-10 16:23:25",
         "type": "library",
         "extra": {
             "branch-alias": {
@@ -660,7 +528,7 @@
         "installation-source": "dist",
         "autoload": {
             "psr-0": {
-                "Symfony\\Component\\DependencyInjection\\": ""
+                "Symfony\\Component\\Validator\\": ""
             }
         },
         "notification-url": "https://packagist.org/downloads/",
@@ -677,29 +545,36 @@
                 "homepage": "http://symfony.com/contributors"
             }
         ],
-        "description": "Symfony DependencyInjection Component",
+        "description": "Symfony Validator Component",
         "homepage": "http://symfony.com"
     },
     {
-        "name": "symfony/serializer",
-        "version": "v2.3.1",
-        "version_normalized": "2.3.1.0",
-        "target-dir": "Symfony/Component/Serializer",
+        "name": "symfony/event-dispatcher",
+        "version": "v2.3.0",
+        "version_normalized": "2.3.0.0",
+        "target-dir": "Symfony/Component/EventDispatcher",
         "source": {
             "type": "git",
-            "url": "https://github.com/symfony/Serializer.git",
-            "reference": "v2.3.1"
+            "url": "https://github.com/symfony/EventDispatcher.git",
+            "reference": "v2.3.0-RC1"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/symfony/Serializer/zipball/v2.3.1",
-            "reference": "v2.3.1",
+            "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.3.0-RC1",
+            "reference": "v2.3.0-RC1",
             "shasum": ""
         },
         "require": {
             "php": ">=5.3.3"
         },
-        "time": "2013-05-10 18:12:13",
+        "require-dev": {
+            "symfony/dependency-injection": ">=2.0,<3.0"
+        },
+        "suggest": {
+            "symfony/dependency-injection": "",
+            "symfony/http-kernel": ""
+        },
+        "time": "2013-05-13 14:36:40",
         "type": "library",
         "extra": {
             "branch-alias": {
@@ -709,7 +584,7 @@
         "installation-source": "dist",
         "autoload": {
             "psr-0": {
-                "Symfony\\Component\\Serializer\\": ""
+                "Symfony\\Component\\EventDispatcher\\": ""
             }
         },
         "notification-url": "https://packagist.org/downloads/",
@@ -726,110 +601,86 @@
                 "homepage": "http://symfony.com/contributors"
             }
         ],
-        "description": "Symfony Serializer Component",
+        "description": "Symfony EventDispatcher Component",
         "homepage": "http://symfony.com"
     },
     {
-        "name": "symfony/translation",
-        "version": "v2.3.0",
-        "version_normalized": "2.3.0.0",
-        "target-dir": "Symfony/Component/Translation",
+        "name": "guzzle/common",
+        "version": "v3.1.2",
+        "version_normalized": "3.1.2.0",
+        "target-dir": "Guzzle/Common",
         "source": {
             "type": "git",
-            "url": "https://github.com/symfony/Translation.git",
-            "reference": "v2.3.0-RC1"
+            "url": "git://github.com/guzzle/common.git",
+            "reference": "v3.1.2"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/symfony/Translation/zipball/v2.3.0-RC1",
-            "reference": "v2.3.0-RC1",
+            "url": "https://github.com/guzzle/common/archive/v3.1.2.zip",
+            "reference": "v3.1.2",
             "shasum": ""
         },
         "require": {
-            "php": ">=5.3.3"
-        },
-        "require-dev": {
-            "symfony/config": ">=2.0,<3.0",
-            "symfony/yaml": ">=2.2,<3.0"
-        },
-        "suggest": {
-            "symfony/config": "",
-            "symfony/yaml": ""
+            "php": ">=5.3.2",
+            "symfony/event-dispatcher": ">=2.1"
         },
-        "time": "2013-05-13 14:36:40",
+        "time": "2013-01-28 00:07:40",
         "type": "library",
         "extra": {
             "branch-alias": {
-                "dev-master": "2.3-dev"
+                "dev-master": "3.0-dev"
             }
         },
         "installation-source": "dist",
         "autoload": {
             "psr-0": {
-                "Symfony\\Component\\Translation\\": ""
+                "Guzzle\\Common": ""
             }
         },
         "notification-url": "https://packagist.org/downloads/",
         "license": [
             "MIT"
         ],
-        "authors": [
-            {
-                "name": "Fabien Potencier",
-                "email": "fabien@symfony.com"
-            },
-            {
-                "name": "Symfony Community",
-                "homepage": "http://symfony.com/contributors"
-            }
-        ],
-        "description": "Symfony Translation Component",
-        "homepage": "http://symfony.com"
+        "description": "Common libraries used by Guzzle",
+        "homepage": "http://guzzlephp.org/",
+        "keywords": [
+            "collection",
+            "common",
+            "event",
+            "exception"
+        ]
     },
     {
-        "name": "symfony/validator",
-        "version": "v2.3.1",
-        "version_normalized": "2.3.1.0",
-        "target-dir": "Symfony/Component/Validator",
+        "name": "guzzle/stream",
+        "version": "v3.1.2",
+        "version_normalized": "3.1.2.0",
+        "target-dir": "Guzzle/Stream",
         "source": {
             "type": "git",
-            "url": "https://github.com/symfony/Validator.git",
-            "reference": "v2.3.1"
+            "url": "https://github.com/guzzle/stream",
+            "reference": "v3.0.7"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/symfony/Validator/zipball/v2.3.1",
-            "reference": "v2.3.1",
+            "url": "https://github.com/guzzle/stream/archive/v3.0.7.zip",
+            "reference": "v3.0.7",
             "shasum": ""
         },
         "require": {
-            "php": ">=5.3.3",
-            "symfony/translation": ">=2.0,<3.0"
-        },
-        "require-dev": {
-            "symfony/config": ">=2.2,<3.0",
-            "symfony/http-foundation": ">=2.1,<3.0",
-            "symfony/intl": ">=2.3,<3.0",
-            "symfony/yaml": ">=2.0,<3.0"
-        },
-        "suggest": {
-            "doctrine/common": "",
-            "symfony/config": "",
-            "symfony/http-foundation": "",
-            "symfony/intl": "",
-            "symfony/yaml": ""
+            "guzzle/common": "self.version",
+            "php": ">=5.3.2"
         },
-        "time": "2013-06-10 16:23:25",
+        "time": "2012-12-07 16:45:11",
         "type": "library",
         "extra": {
             "branch-alias": {
-                "dev-master": "2.3-dev"
+                "dev-master": "3.0-dev"
             }
         },
         "installation-source": "dist",
         "autoload": {
             "psr-0": {
-                "Symfony\\Component\\Validator\\": ""
+                "Guzzle\\Stream": ""
             }
         },
         "notification-url": "https://packagist.org/downloads/",
@@ -838,38 +689,39 @@
         ],
         "authors": [
             {
-                "name": "Fabien Potencier",
-                "email": "fabien@symfony.com"
-            },
-            {
-                "name": "Symfony Community",
-                "homepage": "http://symfony.com/contributors"
+                "name": "Michael Dowling",
+                "email": "mtdowling@gmail.com",
+                "homepage": "https://github.com/mtdowling"
             }
         ],
-        "description": "Symfony Validator Component",
-        "homepage": "http://symfony.com"
+        "description": "Guzzle stream wrapper component",
+        "homepage": "http://guzzlephp.org/",
+        "keywords": [
+            "Guzzle",
+            "component",
+            "stream"
+        ]
     },
     {
-        "name": "guzzle/common",
+        "name": "guzzle/parser",
         "version": "v3.1.2",
         "version_normalized": "3.1.2.0",
-        "target-dir": "Guzzle/Common",
+        "target-dir": "Guzzle/Parser",
         "source": {
             "type": "git",
-            "url": "git://github.com/guzzle/common.git",
+            "url": "git://github.com/guzzle/parser.git",
             "reference": "v3.1.2"
         },
         "dist": {
             "type": "zip",
-            "url": "https://github.com/guzzle/common/archive/v3.1.2.zip",
+            "url": "https://github.com/guzzle/parser/archive/v3.1.2.zip",
             "reference": "v3.1.2",
             "shasum": ""
         },
         "require": {
-            "php": ">=5.3.2",
-            "symfony/event-dispatcher": ">=2.1"
+            "php": ">=5.3.2"
         },
-        "time": "2013-01-28 00:07:40",
+        "time": "2013-01-12 21:43:21",
         "type": "library",
         "extra": {
             "branch-alias": {
@@ -879,43 +731,49 @@
         "installation-source": "dist",
         "autoload": {
             "psr-0": {
-                "Guzzle\\Common": ""
+                "Guzzle\\Parser": ""
             }
         },
         "notification-url": "https://packagist.org/downloads/",
         "license": [
             "MIT"
         ],
-        "description": "Common libraries used by Guzzle",
+        "description": "Interchangeable parsers used by Guzzle",
         "homepage": "http://guzzlephp.org/",
         "keywords": [
-            "collection",
-            "common",
-            "event",
-            "exception"
+            "URI Template",
+            "cookie",
+            "http",
+            "message",
+            "url"
         ]
     },
     {
-        "name": "guzzle/stream",
+        "name": "guzzle/http",
         "version": "v3.1.2",
         "version_normalized": "3.1.2.0",
-        "target-dir": "Guzzle/Stream",
+        "target-dir": "Guzzle/Http",
         "source": {
             "type": "git",
-            "url": "https://github.com/guzzle/stream",
-            "reference": "v3.0.7"
+            "url": "git://github.com/guzzle/http.git",
+            "reference": "v3.1.2"
         },
         "dist": {
             "type": "zip",
-            "url": "https://github.com/guzzle/stream/archive/v3.0.7.zip",
-            "reference": "v3.0.7",
+            "url": "https://github.com/guzzle/http/archive/v3.1.2.zip",
+            "reference": "v3.1.2",
             "shasum": ""
         },
         "require": {
             "guzzle/common": "self.version",
+            "guzzle/parser": "self.version",
+            "guzzle/stream": "self.version",
             "php": ">=5.3.2"
         },
-        "time": "2012-12-07 16:45:11",
+        "suggest": {
+            "ext-curl": "*"
+        },
+        "time": "2013-01-26 08:20:43",
         "type": "library",
         "extra": {
             "branch-alias": {
@@ -925,7 +783,7 @@
         "installation-source": "dist",
         "autoload": {
             "psr-0": {
-                "Guzzle\\Stream": ""
+                "Guzzle\\Http": ""
             }
         },
         "notification-url": "https://packagist.org/downloads/",
@@ -939,96 +797,249 @@
                 "homepage": "https://github.com/mtdowling"
             }
         ],
-        "description": "Guzzle stream wrapper component",
+        "description": "HTTP libraries used by Guzzle",
         "homepage": "http://guzzlephp.org/",
         "keywords": [
             "Guzzle",
-            "component",
-            "stream"
+            "client",
+            "curl",
+            "http",
+            "http client"
         ]
     },
     {
-        "name": "guzzle/parser",
-        "version": "v3.1.2",
-        "version_normalized": "3.1.2.0",
-        "target-dir": "Guzzle/Parser",
+        "name": "symfony/process",
+        "version": "v2.3.1",
+        "version_normalized": "2.3.1.0",
+        "target-dir": "Symfony/Component/Process",
         "source": {
             "type": "git",
-            "url": "git://github.com/guzzle/parser.git",
-            "reference": "v3.1.2"
+            "url": "https://github.com/symfony/Process.git",
+            "reference": "v2.3.1"
         },
         "dist": {
             "type": "zip",
-            "url": "https://github.com/guzzle/parser/archive/v3.1.2.zip",
-            "reference": "v3.1.2",
+            "url": "https://api.github.com/repos/symfony/Process/zipball/v2.3.1",
+            "reference": "v2.3.1",
             "shasum": ""
         },
         "require": {
-            "php": ">=5.3.2"
+            "php": ">=5.3.3"
         },
-        "time": "2013-01-12 21:43:21",
+        "time": "2013-05-06 20:03:44",
         "type": "library",
         "extra": {
             "branch-alias": {
-                "dev-master": "3.0-dev"
+                "dev-master": "2.3-dev"
             }
         },
         "installation-source": "dist",
         "autoload": {
             "psr-0": {
-                "Guzzle\\Parser": ""
+                "Symfony\\Component\\Process\\": ""
             }
         },
         "notification-url": "https://packagist.org/downloads/",
         "license": [
             "MIT"
         ],
-        "description": "Interchangeable parsers used by Guzzle",
-        "homepage": "http://guzzlephp.org/",
+        "authors": [
+            {
+                "name": "Fabien Potencier",
+                "email": "fabien@symfony.com"
+            },
+            {
+                "name": "Symfony Community",
+                "homepage": "http://symfony.com/contributors"
+            }
+        ],
+        "description": "Symfony Process Component",
+        "homepage": "http://symfony.com"
+    },
+    {
+        "name": "kriswallsmith/assetic",
+        "version": "v1.1.1",
+        "version_normalized": "1.1.1.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/kriswallsmith/assetic.git",
+            "reference": "v1.1.1"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/kriswallsmith/assetic/zipball/v1.1.1",
+            "reference": "v1.1.1",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.3.1",
+            "symfony/process": ">=2.1,<3.0"
+        },
+        "require-dev": {
+            "cssmin/cssmin": "*",
+            "joliclic/javascript-packer": "*",
+            "kamicane/packager": "*",
+            "leafo/lessphp": "*",
+            "leafo/scssphp": "*",
+            "leafo/scssphp-compass": "*",
+            "mrclay/minify": "*",
+            "phpunit/phpunit": ">=3.7,<4.0",
+            "ptachoire/cssembed": "*",
+            "twig/twig": ">=1.6,<2.0"
+        },
+        "suggest": {
+            "leafo/lessphp": "Assetic provides the integration with the lessphp LESS compiler",
+            "leafo/scssphp": "Assetic provides the integration with the scssphp SCSS compiler",
+            "leafo/scssphp-compass": "Assetic provides the integration with the SCSS compass plugin",
+            "ptachoire/cssembed": "Assetic provides the integration with phpcssembed to embed data uris",
+            "twig/twig": "Assetic provides the integration with the Twig templating engine"
+        },
+        "time": "2013-06-01 22:13:43",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "1.1-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Assetic": "src/"
+            },
+            "files": [
+                "src/functions.php"
+            ]
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Kris Wallsmith",
+                "email": "kris.wallsmith@gmail.com",
+                "homepage": "http://kriswallsmith.net/"
+            }
+        ],
+        "description": "Asset Management for PHP",
+        "homepage": "https://github.com/kriswallsmith/assetic",
         "keywords": [
-            "URI Template",
-            "cookie",
-            "http",
-            "message",
-            "url"
+            "assets",
+            "compression",
+            "minification"
         ]
     },
     {
-        "name": "guzzle/http",
-        "version": "v3.1.2",
-        "version_normalized": "3.1.2.0",
-        "target-dir": "Guzzle/Http",
+        "name": "symfony/debug",
+        "version": "v2.3.1",
+        "version_normalized": "2.3.1.0",
+        "target-dir": "Symfony/Component/Debug",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/symfony/Debug.git",
+            "reference": "v2.3.1"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/symfony/Debug/zipball/v2.3.1",
+            "reference": "v2.3.1",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.3.3"
+        },
+        "require-dev": {
+            "symfony/http-foundation": ">=2.1,<3.0",
+            "symfony/http-kernel": ">=2.1,<3.0"
+        },
+        "suggest": {
+            "symfony/class-loader": "",
+            "symfony/http-foundation": "",
+            "symfony/http-kernel": ""
+        },
+        "time": "2013-06-02 11:58:44",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "2.3-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Symfony\\Component\\Debug\\": ""
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Fabien Potencier",
+                "email": "fabien@symfony.com"
+            },
+            {
+                "name": "Symfony Community",
+                "homepage": "http://symfony.com/contributors"
+            }
+        ],
+        "description": "Symfony Debug Component",
+        "homepage": "http://symfony.com"
+    },
+    {
+        "name": "symfony/http-kernel",
+        "version": "v2.3.0",
+        "version_normalized": "2.3.0.0",
+        "target-dir": "Symfony/Component/HttpKernel",
         "source": {
             "type": "git",
-            "url": "git://github.com/guzzle/http.git",
-            "reference": "v3.1.2"
+            "url": "https://github.com/symfony/HttpKernel.git",
+            "reference": "v2.3.0"
         },
         "dist": {
             "type": "zip",
-            "url": "https://github.com/guzzle/http/archive/v3.1.2.zip",
-            "reference": "v3.1.2",
+            "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/v2.3.0",
+            "reference": "v2.3.0",
             "shasum": ""
         },
         "require": {
-            "guzzle/common": "self.version",
-            "guzzle/parser": "self.version",
-            "guzzle/stream": "self.version",
-            "php": ">=5.3.2"
+            "php": ">=5.3.3",
+            "psr/log": ">=1.0,<2.0",
+            "symfony/debug": ">=2.3,<3.0",
+            "symfony/event-dispatcher": ">=2.1,<3.0",
+            "symfony/http-foundation": ">=2.2,<3.0"
+        },
+        "require-dev": {
+            "symfony/browser-kit": "2.2.*",
+            "symfony/class-loader": ">=2.1,<3.0",
+            "symfony/config": ">=2.0,<3.0",
+            "symfony/console": "2.2.*",
+            "symfony/dependency-injection": ">=2.0,<3.0",
+            "symfony/finder": ">=2.0,<3.0",
+            "symfony/process": ">=2.0,<3.0",
+            "symfony/routing": ">=2.2,<3.0",
+            "symfony/stopwatch": ">=2.2,<3.0"
         },
         "suggest": {
-            "ext-curl": "*"
+            "symfony/browser-kit": "",
+            "symfony/class-loader": "",
+            "symfony/config": "",
+            "symfony/console": "",
+            "symfony/dependency-injection": "",
+            "symfony/finder": ""
         },
-        "time": "2013-01-26 08:20:43",
+        "time": "2013-06-03 14:13:35",
         "type": "library",
         "extra": {
             "branch-alias": {
-                "dev-master": "3.0-dev"
+                "dev-master": "2.3-dev"
             }
         },
         "installation-source": "dist",
         "autoload": {
             "psr-0": {
-                "Guzzle\\Http": ""
+                "Symfony\\Component\\HttpKernel\\": ""
             }
         },
         "notification-url": "https://packagist.org/downloads/",
@@ -1037,41 +1048,48 @@
         ],
         "authors": [
             {
-                "name": "Michael Dowling",
-                "email": "mtdowling@gmail.com",
-                "homepage": "https://github.com/mtdowling"
+                "name": "Fabien Potencier",
+                "email": "fabien@symfony.com"
+            },
+            {
+                "name": "Symfony Community",
+                "homepage": "http://symfony.com/contributors"
             }
         ],
-        "description": "HTTP libraries used by Guzzle",
-        "homepage": "http://guzzlephp.org/",
-        "keywords": [
-            "Guzzle",
-            "client",
-            "curl",
-            "http",
-            "http client"
-        ]
+        "description": "Symfony HttpKernel Component",
+        "homepage": "http://symfony.com"
     },
     {
-        "name": "symfony/process",
-        "version": "v2.3.1",
-        "version_normalized": "2.3.1.0",
-        "target-dir": "Symfony/Component/Process",
+        "name": "symfony/routing",
+        "version": "v2.3.0",
+        "version_normalized": "2.3.0.0",
+        "target-dir": "Symfony/Component/Routing",
         "source": {
             "type": "git",
-            "url": "https://github.com/symfony/Process.git",
-            "reference": "v2.3.1"
+            "url": "https://github.com/symfony/Routing.git",
+            "reference": "v2.3.0"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/symfony/Process/zipball/v2.3.1",
-            "reference": "v2.3.1",
+            "url": "https://api.github.com/repos/symfony/Routing/zipball/v2.3.0",
+            "reference": "v2.3.0",
             "shasum": ""
         },
         "require": {
             "php": ">=5.3.3"
         },
-        "time": "2013-05-06 20:03:44",
+        "require-dev": {
+            "doctrine/common": ">=2.2,<3.0",
+            "psr/log": ">=1.0,<2.0",
+            "symfony/config": ">=2.2,<3.0",
+            "symfony/yaml": ">=2.0,<3.0"
+        },
+        "suggest": {
+            "doctrine/common": "",
+            "symfony/config": "",
+            "symfony/yaml": ""
+        },
+        "time": "2013-05-20 08:57:26",
         "type": "library",
         "extra": {
             "branch-alias": {
@@ -1081,7 +1099,7 @@
         "installation-source": "dist",
         "autoload": {
             "psr-0": {
-                "Symfony\\Component\\Process\\": ""
+                "Symfony\\Component\\Routing\\": ""
             }
         },
         "notification-url": "https://packagist.org/downloads/",
@@ -1098,48 +1116,35 @@
                 "homepage": "http://symfony.com/contributors"
             }
         ],
-        "description": "Symfony Process Component",
+        "description": "Symfony Routing Component",
         "homepage": "http://symfony.com"
     },
     {
-        "name": "kriswallsmith/assetic",
-        "version": "v1.1.1",
-        "version_normalized": "1.1.1.0",
+        "name": "symfony-cmf/routing",
+        "version": "1.1.0-beta1",
+        "version_normalized": "1.1.0.0-beta1",
+        "target-dir": "Symfony/Cmf/Component/Routing",
         "source": {
             "type": "git",
-            "url": "https://github.com/kriswallsmith/assetic.git",
-            "reference": "v1.1.1"
+            "url": "https://github.com/symfony-cmf/Routing.git",
+            "reference": "1.1.0-beta1"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/kriswallsmith/assetic/zipball/v1.1.1",
-            "reference": "v1.1.1",
+            "url": "https://api.github.com/repos/symfony-cmf/Routing/zipball/1.1.0-beta1",
+            "reference": "1.1.0-beta1",
             "shasum": ""
         },
         "require": {
-            "php": ">=5.3.1",
-            "symfony/process": ">=2.1,<3.0"
-        },
-        "require-dev": {
-            "cssmin/cssmin": "*",
-            "joliclic/javascript-packer": "*",
-            "kamicane/packager": "*",
-            "leafo/lessphp": "*",
-            "leafo/scssphp": "*",
-            "leafo/scssphp-compass": "*",
-            "mrclay/minify": "*",
-            "phpunit/phpunit": ">=3.7,<4.0",
-            "ptachoire/cssembed": "*",
-            "twig/twig": ">=1.6,<2.0"
+            "php": ">=5.3.3",
+            "psr/log": ">=1.0,<2.0",
+            "symfony/http-kernel": ">=2.2,<3.0",
+            "symfony/routing": ">=2.2,<3.0"
         },
         "suggest": {
-            "leafo/lessphp": "Assetic provides the integration with the lessphp LESS compiler",
-            "leafo/scssphp": "Assetic provides the integration with the scssphp SCSS compiler",
-            "leafo/scssphp-compass": "Assetic provides the integration with the SCSS compass plugin",
-            "ptachoire/cssembed": "Assetic provides the integration with phpcssembed to embed data uris",
-            "twig/twig": "Assetic provides the integration with the Twig templating engine"
+            "symfony/http-foundation": "ChainRouter/DynamicRouter have optional support for Request instances, several enhancers require a Request instances, ~2.2"
         },
-        "time": "2013-06-01 22:13:43",
+        "time": "2013-06-03 17:23:01",
         "type": "library",
         "extra": {
             "branch-alias": {
@@ -1149,11 +1154,8 @@
         "installation-source": "dist",
         "autoload": {
             "psr-0": {
-                "Assetic": "src/"
-            },
-            "files": [
-                "src/functions.php"
-            ]
+                "Symfony\\Cmf\\Component\\Routing": ""
+            }
         },
         "notification-url": "https://packagist.org/downloads/",
         "license": [
@@ -1161,33 +1163,31 @@
         ],
         "authors": [
             {
-                "name": "Kris Wallsmith",
-                "email": "kris.wallsmith@gmail.com",
-                "homepage": "http://kriswallsmith.net/"
+                "name": "Symfony CMF Community",
+                "homepage": "https://github.com/symfony-cmf/Routing/contributors"
             }
         ],
-        "description": "Asset Management for PHP",
-        "homepage": "https://github.com/kriswallsmith/assetic",
+        "description": "Extends the Symfony2 routing component for dynamic routes and chaining several routers",
+        "homepage": "http://cmf.symfony.com",
         "keywords": [
-            "assets",
-            "compression",
-            "minification"
+            "database",
+            "routing"
         ]
     },
     {
         "name": "symfony/yaml",
-        "version": "v2.3.0",
-        "version_normalized": "2.3.0.0",
+        "version": "v2.3.1",
+        "version_normalized": "2.3.1.0",
         "target-dir": "Symfony/Component/Yaml",
         "source": {
             "type": "git",
             "url": "https://github.com/symfony/Yaml.git",
-            "reference": "v2.3.0-RC1"
+            "reference": "v2.3.1"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/symfony/Yaml/zipball/v2.3.0-RC1",
-            "reference": "v2.3.0-RC1",
+            "url": "https://api.github.com/repos/symfony/Yaml/zipball/v2.3.1",
+            "reference": "v2.3.1",
             "shasum": ""
         },
         "require": {
@@ -1593,5 +1593,143 @@
             "testing",
             "xunit"
         ]
+    },
+    {
+        "name": "zendframework/zend-stdlib",
+        "version": "2.2.1",
+        "version_normalized": "2.2.1.0",
+        "target-dir": "Zend/Stdlib",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/zendframework/Component_ZendStdlib.git",
+            "reference": "release-2.2.1"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/zendframework/Component_ZendStdlib/zipball/release-2.2.1",
+            "reference": "release-2.2.1",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.3.3"
+        },
+        "suggest": {
+            "zendframework/zend-eventmanager": "To support aggregate hydrator usage",
+            "zendframework/zend-servicemanager": "To support hydrator plugin manager usage"
+        },
+        "time": "2013-06-12 19:46:58",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "2.2-dev",
+                "dev-develop": "2.3-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Zend\\Stdlib\\": ""
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "BSD-3-Clause"
+        ],
+        "keywords": [
+            "stdlib",
+            "zf2"
+        ]
+    },
+    {
+        "name": "zendframework/zend-escaper",
+        "version": "2.2.1",
+        "version_normalized": "2.2.1.0",
+        "target-dir": "Zend/Escaper",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/zendframework/Component_ZendEscaper.git",
+            "reference": "release-2.2.1"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/zendframework/Component_ZendEscaper/zipball/release-2.2.1",
+            "reference": "release-2.2.1",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.3.3"
+        },
+        "time": "2013-05-01 21:53:03",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "2.2-dev",
+                "dev-develop": "2.3-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Zend\\Escaper\\": ""
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "BSD-3-Clause"
+        ],
+        "keywords": [
+            "escaper",
+            "zf2"
+        ]
+    },
+    {
+        "name": "zendframework/zend-feed",
+        "version": "2.2.1",
+        "version_normalized": "2.2.1.0",
+        "target-dir": "Zend/Feed",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/zendframework/Component_ZendFeed.git",
+            "reference": "release-2.2.1"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/zendframework/Component_ZendFeed/zipball/release-2.2.1",
+            "reference": "release-2.2.1",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.3.3",
+            "zendframework/zend-escaper": "self.version",
+            "zendframework/zend-stdlib": "self.version"
+        },
+        "suggest": {
+            "zendframework/zend-http": "Zend\\Http for PubSubHubbub, and optionally for use with Zend\\Feed\\Reader",
+            "zendframework/zend-servicemanager": "Zend\\ServiceManager component, for default/recommended ExtensionManager implementations",
+            "zendframework/zend-validator": "Zend\\Validator component"
+        },
+        "time": "2013-06-12 19:45:31",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "2.2-dev",
+                "dev-develop": "2.3-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Zend\\Feed\\": ""
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "BSD-3-Clause"
+        ],
+        "description": "provides functionality for consuming RSS and Atom feeds",
+        "keywords": [
+            "feed",
+            "zf2"
+        ]
     }
 ]
diff --git a/core/vendor/symfony-cmf/routing/Symfony/Cmf/Component/Routing/.travis.yml b/core/vendor/symfony-cmf/routing/Symfony/Cmf/Component/Routing/.travis.yml
index 9c9cce938e40..494db9829aea 100644
--- a/core/vendor/symfony-cmf/routing/Symfony/Cmf/Component/Routing/.travis.yml
+++ b/core/vendor/symfony-cmf/routing/Symfony/Cmf/Component/Routing/.travis.yml
@@ -6,6 +6,7 @@ php:
 
 env:
   - SYMFONY_VERSION=2.2.*
+  - SYMFONY_VERSION=2.3.*
   - SYMFONY_VERSION=dev-master
 
 before_script:
diff --git a/core/vendor/symfony-cmf/routing/Symfony/Cmf/Component/Routing/CHANGELOG.md b/core/vendor/symfony-cmf/routing/Symfony/Cmf/Component/Routing/CHANGELOG.md
index a93a031d4dce..fe5dcfc79879 100644
--- a/core/vendor/symfony-cmf/routing/Symfony/Cmf/Component/Routing/CHANGELOG.md
+++ b/core/vendor/symfony-cmf/routing/Symfony/Cmf/Component/Routing/CHANGELOG.md
@@ -1,6 +1,8 @@
-# Changelog
+Changelog
+=========
 
-## 1.1
+1.1
+---
 
-* Dropped Symfony 2.1 support and got rid of ConfigurableUrlMatcher class
-* Fix locale handling to always respect locale but never have unnecessary ?locale=
\ No newline at end of file
+* **2013-04-30**: Dropped Symfony 2.1 support and got rid of ConfigurableUrlMatcher class
+* **2013-04-05**: [ContentAwareGenerator] Fix locale handling to always respect locale but never have unnecessary ?locale=
diff --git a/core/vendor/symfony-cmf/routing/Symfony/Cmf/Component/Routing/composer.json b/core/vendor/symfony-cmf/routing/Symfony/Cmf/Component/Routing/composer.json
index 8559c1aa7616..63cfa9b29386 100644
--- a/core/vendor/symfony-cmf/routing/Symfony/Cmf/Component/Routing/composer.json
+++ b/core/vendor/symfony-cmf/routing/Symfony/Cmf/Component/Routing/composer.json
@@ -13,13 +13,13 @@
     ],
     "minimum-stability": "dev",
     "require": {
-        "php": ">=5.3.2",
-        "symfony/routing": ">=2.2,<2.4-dev",
-        "symfony/http-kernel": ">=2.2,<2.4-dev",
+        "php": ">=5.3.3",
+        "symfony/routing": "~2.2",
+        "symfony/http-kernel": "~2.2",
         "psr/log": "~1.0"
     },
     "suggest": {
-        "symfony/http-foundation": "ChainRouter/DynamicRouter have optional support for Request instances, several enhancers require a Request instances, >=2.2,<2.3-dev"
+        "symfony/http-foundation": "ChainRouter/DynamicRouter have optional support for Request instances, several enhancers require a Request instances, ~2.2"
     },
     "autoload": {
         "psr-0": { "Symfony\\Cmf\\Component\\Routing": "" }
diff --git a/core/vendor/zendframework/zend-escaper/Zend/Escaper/Escaper.php b/core/vendor/zendframework/zend-escaper/Zend/Escaper/Escaper.php
new file mode 100644
index 000000000000..38ab113e9db5
--- /dev/null
+++ b/core/vendor/zendframework/zend-escaper/Zend/Escaper/Escaper.php
@@ -0,0 +1,390 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Escaper;
+
+use Zend\Escaper\Exception;
+
+/**
+ * Context specific methods for use in secure output escaping
+ */
+class Escaper
+{
+    /**
+     * Entity Map mapping Unicode codepoints to any available named HTML entities.
+     *
+     * While HTML supports far more named entities, the lowest common denominator
+     * has become HTML5's XML Serialisation which is restricted to the those named
+     * entities that XML supports. Using HTML entities would result in this error:
+     *     XML Parsing Error: undefined entity
+     *
+     * @var array
+     */
+    protected static $htmlNamedEntityMap = array(
+        34 => 'quot',         // quotation mark
+        38 => 'amp',          // ampersand
+        60 => 'lt',           // less-than sign
+        62 => 'gt',           // greater-than sign
+    );
+
+    /**
+     * Current encoding for escaping. If not UTF-8, we convert strings from this encoding
+     * pre-escaping and back to this encoding post-escaping.
+     *
+     * @var string
+     */
+    protected $encoding = 'utf-8';
+
+    /**
+     * Holds the value of the special flags passed as second parameter to
+     * htmlspecialchars(). We modify these for PHP 5.4 to take advantage
+     * of the new ENT_SUBSTITUTE flag for correctly dealing with invalid
+     * UTF-8 sequences.
+     *
+     * @var string
+     */
+    protected $htmlSpecialCharsFlags = ENT_QUOTES;
+
+    /**
+     * Static Matcher which escapes characters for HTML Attribute contexts
+     *
+     * @var callable
+     */
+    protected $htmlAttrMatcher;
+
+    /**
+     * Static Matcher which escapes characters for Javascript contexts
+     *
+     * @var callable
+     */
+    protected $jsMatcher;
+
+    /**
+     * Static Matcher which escapes characters for CSS Attribute contexts
+     *
+     * @var callable
+     */
+    protected $cssMatcher;
+
+    /**
+     * List of all encoding supported by this class
+     *
+     * @var array
+     */
+    protected $supportedEncodings = array(
+        'iso-8859-1',   'iso8859-1',    'iso-8859-5',   'iso8859-5',
+        'iso-8859-15',  'iso8859-15',   'utf-8',        'cp866',
+        'ibm866',       '866',          'cp1251',       'windows-1251',
+        'win-1251',     '1251',         'cp1252',       'windows-1252',
+        '1252',         'koi8-r',       'koi8-ru',      'koi8r',
+        'big5',         '950',          'gb2312',       '936',
+        'big5-hkscs',   'shift_jis',    'sjis',         'sjis-win',
+        'cp932',        '932',          'euc-jp',       'eucjp',
+        'eucjp-win',    'macroman'
+    );
+
+    /**
+     * Constructor: Single parameter allows setting of global encoding for use by
+     * the current object. If PHP 5.4 is detected, additional ENT_SUBSTITUTE flag
+     * is set for htmlspecialchars() calls.
+     *
+     * @param string $encoding
+     * @throws Exception\InvalidArgumentException
+     */
+    public function __construct($encoding = null)
+    {
+        if ($encoding !== null) {
+            $encoding = (string) $encoding;
+            if ($encoding === '') {
+                throw new Exception\InvalidArgumentException(
+                    get_class($this) . ' constructor parameter does not allow a blank value'
+                );
+            }
+
+            $encoding = strtolower($encoding);
+            if (!in_array($encoding, $this->supportedEncodings)) {
+                throw new Exception\InvalidArgumentException(
+                    'Value of \'' . $encoding . '\' passed to ' . get_class($this)
+                    . ' constructor parameter is invalid. Provide an encoding supported by htmlspecialchars()'
+                );
+            }
+
+            $this->encoding = $encoding;
+        }
+
+        if (defined('ENT_SUBSTITUTE')) {
+            $this->htmlSpecialCharsFlags|= ENT_SUBSTITUTE;
+        }
+
+        // set matcher callbacks
+        $this->htmlAttrMatcher = array($this, 'htmlAttrMatcher');
+        $this->jsMatcher       = array($this, 'jsMatcher');
+        $this->cssMatcher      = array($this, 'cssMatcher');
+    }
+
+    /**
+     * Return the encoding that all output/input is expected to be encoded in.
+     *
+     * @return string
+     */
+    public function getEncoding()
+    {
+        return $this->encoding;
+    }
+
+    /**
+     * Escape a string for the HTML Body context where there are very few characters
+     * of special meaning. Internally this will use htmlspecialchars().
+     *
+     * @param string $string
+     * @return string
+     */
+    public function escapeHtml($string)
+    {
+        $result = htmlspecialchars($string, $this->htmlSpecialCharsFlags, $this->encoding);
+        return $result;
+    }
+
+    /**
+     * Escape a string for the HTML Attribute context. We use an extended set of characters
+     * to escape that are not covered by htmlspecialchars() to cover cases where an attribute
+     * might be unquoted or quoted illegally (e.g. backticks are valid quotes for IE).
+     *
+     * @param string $string
+     * @return string
+     */
+    public function escapeHtmlAttr($string)
+    {
+        $string = $this->toUtf8($string);
+        if ($string === '' || ctype_digit($string)) {
+            return $string;
+        }
+
+        $result = preg_replace_callback('/[^a-z0-9,\.\-_]/iSu', $this->htmlAttrMatcher, $string);
+        return $this->fromUtf8($result);
+    }
+
+    /**
+     * Escape a string for the Javascript context. This does not use json_encode(). An extended
+     * set of characters are escaped beyond ECMAScript's rules for Javascript literal string
+     * escaping in order to prevent misinterpretation of Javascript as HTML leading to the
+     * injection of special characters and entities. The escaping used should be tolerant
+     * of cases where HTML escaping was not applied on top of Javascript escaping correctly.
+     * Backslash escaping is not used as it still leaves the escaped character as-is and so
+     * is not useful in a HTML context.
+     *
+     * @param string $string
+     * @return string
+     */
+    public function escapeJs($string)
+    {
+        $string = $this->toUtf8($string);
+        if ($string === '' || ctype_digit($string)) {
+            return $string;
+        }
+
+        $result = preg_replace_callback('/[^a-z0-9,\._]/iSu', $this->jsMatcher, $string);
+        return $this->fromUtf8($result);
+    }
+
+    /**
+     * Escape a string for the URI or Parameter contexts. This should not be used to escape
+     * an entire URI - only a subcomponent being inserted. The function is a simple proxy
+     * to rawurlencode() which now implements RFC 3986 since PHP 5.3 completely.
+     *
+     * @param string $string
+     * @return string
+     */
+    public function escapeUrl($string)
+    {
+        return rawurlencode($string);
+    }
+
+    /**
+     * Escape a string for the CSS context. CSS escaping can be applied to any string being
+     * inserted into CSS and escapes everything except alphanumerics.
+     *
+     * @param string $string
+     * @return string
+     */
+    public function escapeCss($string)
+    {
+        $string = $this->toUtf8($string);
+        if ($string === '' || ctype_digit($string)) {
+            return $string;
+        }
+
+        $result = preg_replace_callback('/[^a-z0-9]/iSu', $this->cssMatcher, $string);
+        return $this->fromUtf8($result);
+    }
+
+    /**
+     * Callback function for preg_replace_callback that applies HTML Attribute
+     * escaping to all matches.
+     *
+     * @param array $matches
+     * @return string
+     */
+    protected function htmlAttrMatcher($matches)
+    {
+        $chr = $matches[0];
+        $ord = ord($chr);
+
+        /**
+         * The following replaces characters undefined in HTML with the
+         * hex entity for the Unicode replacement character.
+         */
+        if (($ord <= 0x1f && $chr != "\t" && $chr != "\n" && $chr != "\r")
+            || ($ord >= 0x7f && $ord <= 0x9f)
+        ) {
+            return '&#xFFFD;';
+        }
+
+        /**
+         * Check if the current character to escape has a name entity we should
+         * replace it with while grabbing the integer value of the character.
+         */
+        if (strlen($chr) > 1) {
+            $chr = $this->convertEncoding($chr, 'UTF-16BE', 'UTF-8');
+        }
+
+        $hex = bin2hex($chr);
+        $ord = hexdec($hex);
+        if (isset(static::$htmlNamedEntityMap[$ord])) {
+            return '&' . static::$htmlNamedEntityMap[$ord] . ';';
+        }
+
+        /**
+         * Per OWASP recommendations, we'll use upper hex entities
+         * for any other characters where a named entity does not exist.
+         */
+        if ($ord > 255) {
+            return sprintf('&#x%04X;', $ord);
+        }
+        return sprintf('&#x%02X;', $ord);
+    }
+
+    /**
+     * Callback function for preg_replace_callback that applies Javascript
+     * escaping to all matches.
+     *
+     * @param array $matches
+     * @return string
+     */
+    protected function jsMatcher($matches)
+    {
+        $chr = $matches[0];
+        if (strlen($chr) == 1) {
+            return sprintf('\\x%02X', ord($chr));
+        }
+        $chr = $this->convertEncoding($chr, 'UTF-16BE', 'UTF-8');
+        return sprintf('\\u%04s', strtoupper(bin2hex($chr)));
+    }
+
+    /**
+     * Callback function for preg_replace_callback that applies CSS
+     * escaping to all matches.
+     *
+     * @param array $matches
+     * @return string
+     */
+    protected function cssMatcher($matches)
+    {
+        $chr = $matches[0];
+        if (strlen($chr) == 1) {
+            $ord = ord($chr);
+        } else {
+            $chr = $this->convertEncoding($chr, 'UTF-16BE', 'UTF-8');
+            $ord = hexdec(bin2hex($chr));
+        }
+        return sprintf('\\%X ', $ord);
+    }
+
+    /**
+     * Converts a string to UTF-8 from the base encoding. The base encoding is set via this
+     * class' constructor.
+     *
+     * @param string $string
+     * @throws Exception\RuntimeException
+     * @return string
+     */
+    protected function toUtf8($string)
+    {
+        if ($this->getEncoding() === 'utf-8') {
+            $result = $string;
+        } else {
+            $result = $this->convertEncoding($string, 'UTF-8', $this->getEncoding());
+        }
+
+        if (!$this->isUtf8($result)) {
+            throw new Exception\RuntimeException(sprintf(
+                'String to be escaped was not valid UTF-8 or could not be converted: %s', $result
+            ));
+        }
+
+        return $result;
+    }
+
+    /**
+     * Converts a string from UTF-8 to the base encoding. The base encoding is set via this
+     * class' constructor.
+     * @param string $string
+     * @return string
+     */
+    protected function fromUtf8($string)
+    {
+        if ($this->getEncoding() === 'utf-8') {
+            return $string;
+        }
+
+        return $this->convertEncoding($string, $this->getEncoding(), 'UTF-8');
+    }
+
+    /**
+     * Checks if a given string appears to be valid UTF-8 or not.
+     *
+     * @param string $string
+     * @return bool
+     */
+    protected function isUtf8($string)
+    {
+        return ($string === '' || preg_match('/^./su', $string));
+    }
+
+    /**
+     * Encoding conversion helper which wraps iconv and mbstring where they exist or throws
+     * and exception where neither is available.
+     *
+     * @param string $string
+     * @param string $to
+     * @param array|string $from
+     * @throws Exception\RuntimeException
+     * @return string
+     */
+    protected function convertEncoding($string, $to, $from)
+    {
+        $result = '';
+        if (function_exists('iconv')) {
+            $result = iconv($from, $to, $string);
+        } elseif (function_exists('mb_convert_encoding')) {
+            $result = mb_convert_encoding($string, $to, $from);
+        } else {
+            throw new Exception\RuntimeException(
+                get_class($this)
+                . ' requires either the iconv or mbstring extension to be installed'
+                . ' when escaping for non UTF-8 strings.'
+            );
+        }
+
+        if ($result === false) {
+            return ''; // return non-fatal blank string on encoding errors from users
+        }
+        return $result;
+    }
+}
diff --git a/core/vendor/zendframework/zend-escaper/Zend/Escaper/Exception/ExceptionInterface.php b/core/vendor/zendframework/zend-escaper/Zend/Escaper/Exception/ExceptionInterface.php
new file mode 100644
index 000000000000..364dd67e939e
--- /dev/null
+++ b/core/vendor/zendframework/zend-escaper/Zend/Escaper/Exception/ExceptionInterface.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Escaper\Exception;
+
+interface ExceptionInterface
+{}
diff --git a/core/vendor/zendframework/zend-escaper/Zend/Escaper/Exception/InvalidArgumentException.php b/core/vendor/zendframework/zend-escaper/Zend/Escaper/Exception/InvalidArgumentException.php
new file mode 100644
index 000000000000..78c4da7993c8
--- /dev/null
+++ b/core/vendor/zendframework/zend-escaper/Zend/Escaper/Exception/InvalidArgumentException.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Escaper\Exception;
+
+/**
+ * Invalid argument exception
+ */
+class InvalidArgumentException extends \InvalidArgumentException implements
+    ExceptionInterface
+{
+}
diff --git a/core/vendor/zendframework/zend-escaper/Zend/Escaper/Exception/RuntimeException.php b/core/vendor/zendframework/zend-escaper/Zend/Escaper/Exception/RuntimeException.php
new file mode 100644
index 000000000000..dec2501d2982
--- /dev/null
+++ b/core/vendor/zendframework/zend-escaper/Zend/Escaper/Exception/RuntimeException.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Escaper\Exception;
+
+/**
+ * Invalid argument exception
+ */
+class RuntimeException extends \RuntimeException implements
+    ExceptionInterface
+{
+}
diff --git a/core/vendor/zendframework/zend-escaper/Zend/Escaper/README.md b/core/vendor/zendframework/zend-escaper/Zend/Escaper/README.md
new file mode 100644
index 000000000000..83bd91628059
--- /dev/null
+++ b/core/vendor/zendframework/zend-escaper/Zend/Escaper/README.md
@@ -0,0 +1,15 @@
+Escaper Component from ZF2
+==========================
+
+This is the Escaper component for ZF2.
+
+- File issues at https://github.com/zendframework/zf2/issues
+- Create pull requests against https://github.com/zendframework/zf2
+- Documentation is at http://framework.zend.com/docs
+
+LICENSE
+-------
+
+The files in this archive are released under the [Zend Framework
+license](http://framework.zend.com/license), which is a 3-clause BSD license.
+
diff --git a/core/vendor/zendframework/zend-escaper/Zend/Escaper/composer.json b/core/vendor/zendframework/zend-escaper/Zend/Escaper/composer.json
new file mode 100644
index 000000000000..3b2f2b602d4f
--- /dev/null
+++ b/core/vendor/zendframework/zend-escaper/Zend/Escaper/composer.json
@@ -0,0 +1,24 @@
+{
+    "name": "zendframework/zend-escaper",
+    "description": " ",
+    "license": "BSD-3-Clause",
+    "keywords": [
+        "zf2",
+        "escaper"
+    ],
+    "autoload": {
+        "psr-0": {
+            "Zend\\Escaper\\": ""
+        }
+    },
+    "target-dir": "Zend/Escaper",
+    "require": {
+        "php": ">=5.3.3"
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "2.2-dev",
+            "dev-develop": "2.3-dev"
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Exception/BadMethodCallException.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Exception/BadMethodCallException.php
new file mode 100644
index 000000000000..34ab71874bde
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Exception/BadMethodCallException.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Exception;
+
+class BadMethodCallException
+    extends \BadMethodCallException
+    implements ExceptionInterface
+{}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Exception/ExceptionInterface.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Exception/ExceptionInterface.php
new file mode 100644
index 000000000000..f4cf0a0ba5e0
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Exception/ExceptionInterface.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Exception;
+
+interface ExceptionInterface
+{}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Exception/InvalidArgumentException.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Exception/InvalidArgumentException.php
new file mode 100644
index 000000000000..09930c9b5197
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Exception/InvalidArgumentException.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Exception;
+
+class InvalidArgumentException
+    extends \InvalidArgumentException
+    implements ExceptionInterface
+{}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Exception/RuntimeException.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Exception/RuntimeException.php
new file mode 100644
index 000000000000..27a32c6bbf2d
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Exception/RuntimeException.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Exception;
+
+class RuntimeException
+    extends \RuntimeException
+    implements ExceptionInterface
+{}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/AbstractCallback.php b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/AbstractCallback.php
new file mode 100644
index 000000000000..b3ab1907465a
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/AbstractCallback.php
@@ -0,0 +1,291 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\PubSubHubbub;
+
+use Traversable;
+use Zend\Http\PhpEnvironment\Response as PhpResponse;
+use Zend\Stdlib\ArrayUtils;
+
+abstract class AbstractCallback implements CallbackInterface
+{
+    /**
+     * An instance of Zend\Feed\Pubsubhubbub\Model\SubscriptionPersistenceInterface
+     * used to background save any verification tokens associated with a subscription
+     * or other.
+     *
+     * @var Model\SubscriptionPersistenceInterface
+     */
+    protected $storage = null;
+
+    /**
+     * An instance of a class handling Http Responses. This is implemented in
+     * Zend\Feed\Pubsubhubbub\HttpResponse which shares an unenforced interface with
+     * (i.e. not inherited from) Zend\Controller\Response\Http.
+     *
+     * @var HttpResponse|PhpResponse
+     */
+    protected $httpResponse = null;
+
+    /**
+     * The number of Subscribers for which any updates are on behalf of.
+     *
+     * @var int
+     */
+    protected $subscriberCount = 1;
+
+    /**
+     * Constructor; accepts an array or Traversable object to preset
+     * options for the Subscriber without calling all supported setter
+     * methods in turn.
+     *
+     * @param  array|Traversable $options Options array or Traversable object
+     */
+    public function __construct($options = null)
+    {
+        if ($options !== null) {
+            $this->setOptions($options);
+        }
+    }
+
+    /**
+     * Process any injected configuration options
+     *
+     * @param  array|Traversable $options Options array or Traversable object
+     * @return AbstractCallback
+     * @throws Exception\InvalidArgumentException
+     */
+    public function setOptions($options)
+    {
+        if ($options instanceof Traversable) {
+            $options = ArrayUtils::iteratorToArray($options);
+        }
+
+        if (!is_array($options)) {
+            throw new Exception\InvalidArgumentException('Array or Traversable object'
+            . 'expected, got ' . gettype($options));
+        }
+
+        if (is_array($options)) {
+            $this->setOptions($options);
+        }
+
+        if (array_key_exists('storage', $options)) {
+            $this->setStorage($options['storage']);
+        }
+        return $this;
+    }
+
+    /**
+     * Send the response, including all headers.
+     * If you wish to handle this via Zend\Http, use the getter methods
+     * to retrieve any data needed to be set on your HTTP Response object, or
+     * simply give this object the HTTP Response instance to work with for you!
+     *
+     * @return void
+     */
+    public function sendResponse()
+    {
+        $this->getHttpResponse()->send();
+    }
+
+    /**
+     * Sets an instance of Zend\Feed\Pubsubhubbub\Model\SubscriptionPersistence used
+     * to background save any verification tokens associated with a subscription
+     * or other.
+     *
+     * @param  Model\SubscriptionPersistenceInterface $storage
+     * @return AbstractCallback
+     */
+    public function setStorage(Model\SubscriptionPersistenceInterface $storage)
+    {
+        $this->storage = $storage;
+        return $this;
+    }
+
+    /**
+     * Gets an instance of Zend\Feed\Pubsubhubbub\Model\SubscriptionPersistence used
+     * to background save any verification tokens associated with a subscription
+     * or other.
+     *
+     * @return Model\SubscriptionPersistenceInterface
+     * @throws Exception\RuntimeException
+     */
+    public function getStorage()
+    {
+        if ($this->storage === null) {
+            throw new Exception\RuntimeException('No storage object has been'
+                . ' set that subclasses Zend\Feed\Pubsubhubbub\Model\SubscriptionPersistence');
+        }
+        return $this->storage;
+    }
+
+    /**
+     * An instance of a class handling Http Responses. This is implemented in
+     * Zend\Feed\Pubsubhubbub\HttpResponse which shares an unenforced interface with
+     * (i.e. not inherited from) Zend\Controller\Response\Http.
+     *
+     * @param  HttpResponse|PhpResponse $httpResponse
+     * @return AbstractCallback
+     * @throws Exception\InvalidArgumentException
+     */
+    public function setHttpResponse($httpResponse)
+    {
+        if (!$httpResponse instanceof HttpResponse && !$httpResponse instanceof PhpResponse) {
+            throw new Exception\InvalidArgumentException('HTTP Response object must'
+                . ' implement one of Zend\Feed\Pubsubhubbub\HttpResponse or'
+                . ' Zend\Http\PhpEnvironment\Response');
+        }
+        $this->httpResponse = $httpResponse;
+        return $this;
+    }
+
+    /**
+     * An instance of a class handling Http Responses. This is implemented in
+     * Zend\Feed\Pubsubhubbub\HttpResponse which shares an unenforced interface with
+     * (i.e. not inherited from) Zend\Controller\Response\Http.
+     *
+     * @return HttpResponse|PhpResponse
+     */
+    public function getHttpResponse()
+    {
+        if ($this->httpResponse === null) {
+            $this->httpResponse = new HttpResponse;
+        }
+        return $this->httpResponse;
+    }
+
+    /**
+     * Sets the number of Subscribers for which any updates are on behalf of.
+     * In other words, is this class serving one or more subscribers? How many?
+     * Defaults to 1 if left unchanged.
+     *
+     * @param  string|int $count
+     * @return AbstractCallback
+     * @throws Exception\InvalidArgumentException
+     */
+    public function setSubscriberCount($count)
+    {
+        $count = intval($count);
+        if ($count <= 0) {
+            throw new Exception\InvalidArgumentException('Subscriber count must be'
+                . ' greater than zero');
+        }
+        $this->subscriberCount = $count;
+        return $this;
+    }
+
+    /**
+     * Gets the number of Subscribers for which any updates are on behalf of.
+     * In other words, is this class serving one or more subscribers? How many?
+     *
+     * @return int
+     */
+    public function getSubscriberCount()
+    {
+        return $this->subscriberCount;
+    }
+
+    /**
+     * Attempt to detect the callback URL (specifically the path forward)
+     * @return string
+     */
+    protected function _detectCallbackUrl()
+    {
+        $callbackUrl = '';
+        if (isset($_SERVER['HTTP_X_ORIGINAL_URL'])) {
+            $callbackUrl = $_SERVER['HTTP_X_ORIGINAL_URL'];
+        } elseif (isset($_SERVER['HTTP_X_REWRITE_URL'])) {
+            $callbackUrl = $_SERVER['HTTP_X_REWRITE_URL'];
+        } elseif (isset($_SERVER['REQUEST_URI'])) {
+            $callbackUrl = $_SERVER['REQUEST_URI'];
+            $scheme = 'http';
+            if ($_SERVER['HTTPS'] == 'on') {
+                $scheme = 'https';
+            }
+            $schemeAndHttpHost = $scheme . '://' . $this->_getHttpHost();
+            if (strpos($callbackUrl, $schemeAndHttpHost) === 0) {
+                $callbackUrl = substr($callbackUrl, strlen($schemeAndHttpHost));
+            }
+        } elseif (isset($_SERVER['ORIG_PATH_INFO'])) {
+            $callbackUrl= $_SERVER['ORIG_PATH_INFO'];
+            if (!empty($_SERVER['QUERY_STRING'])) {
+                $callbackUrl .= '?' . $_SERVER['QUERY_STRING'];
+            }
+        }
+        return $callbackUrl;
+    }
+
+    /**
+     * Get the HTTP host
+     *
+     * @return string
+     */
+    protected function _getHttpHost()
+    {
+        if (!empty($_SERVER['HTTP_HOST'])) {
+            return $_SERVER['HTTP_HOST'];
+        }
+        $scheme = 'http';
+        if ($_SERVER['HTTPS'] == 'on') {
+            $scheme = 'https';
+        }
+        $name = $_SERVER['SERVER_NAME'];
+        $port = $_SERVER['SERVER_PORT'];
+        if (($scheme == 'http' && $port == 80)
+            || ($scheme == 'https' && $port == 443)
+        ) {
+            return $name;
+        }
+
+        return $name . ':' . $port;
+    }
+
+    /**
+     * Retrieve a Header value from either $_SERVER or Apache
+     *
+     * @param string $header
+     * @return bool|string
+     */
+    protected function _getHeader($header)
+    {
+        $temp = strtoupper(str_replace('-', '_', $header));
+        if (!empty($_SERVER[$temp])) {
+            return $_SERVER[$temp];
+        }
+        $temp = 'HTTP_' . strtoupper(str_replace('-', '_', $header));
+        if (!empty($_SERVER[$temp])) {
+            return $_SERVER[$temp];
+        }
+        if (function_exists('apache_request_headers')) {
+            $headers = apache_request_headers();
+            if (!empty($headers[$header])) {
+                return $headers[$header];
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Return the raw body of the request
+     *
+     * @return string|false Raw body, or false if not present
+     */
+    protected function _getRawBody()
+    {
+        $body = file_get_contents('php://input');
+        if (strlen(trim($body)) == 0 && isset($GLOBALS['HTTP_RAW_POST_DATA'])) {
+            $body = $GLOBALS['HTTP_RAW_POST_DATA'];
+        }
+        if (strlen(trim($body)) > 0) {
+            return $body;
+        }
+        return false;
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/CallbackInterface.php b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/CallbackInterface.php
new file mode 100644
index 000000000000..9bcc6e2f900a
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/CallbackInterface.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\PubSubHubbub;
+
+interface CallbackInterface
+{
+    /**
+     * Handle any callback from a Hub Server responding to a subscription or
+     * unsubscription request. This should be the Hub Server confirming the
+     * the request prior to taking action on it.
+     *
+     * @param array $httpData GET/POST data if available and not in $_GET/POST
+     * @param bool $sendResponseNow Whether to send response now or when asked
+     */
+    public function handle(array $httpData = null, $sendResponseNow = false);
+
+    /**
+     * Send the response, including all headers.
+     * If you wish to handle this via Controller, use the getter methods
+     * to retrieve any data needed to be set on your HTTP Response object, or
+     * simply give this object the HTTP Response instance to work with for you!
+     *
+     * @return void
+     */
+    public function sendResponse();
+
+    /**
+     * An instance of a class handling Http Responses. This is implemented in
+     * Zend\Feed\Pubsubhubbub\HttpResponse which shares an unenforced interface with
+     * (i.e. not inherited from) Zend\Feed\Pubsubhubbub\AbstractCallback.
+     *
+     * @param HttpResponse|\Zend\Http\PhpEnvironment\Response $httpResponse
+     */
+    public function setHttpResponse($httpResponse);
+
+    /**
+     * An instance of a class handling Http Responses. This is implemented in
+     * Zend\Feed\Pubsubhubbub\HttpResponse which shares an unenforced interface with
+     * (i.e. not inherited from) Zend\Feed\Pubsubhubbub\AbstractCallback.
+     *
+     * @return HttpResponse|\Zend\Http\PhpEnvironment\Response
+     */
+    public function getHttpResponse();
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Exception/ExceptionInterface.php b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Exception/ExceptionInterface.php
new file mode 100644
index 000000000000..75d710cd7093
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Exception/ExceptionInterface.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\PubSubHubbub\Exception;
+
+use Zend\Feed\Exception\ExceptionInterface as Exception;
+
+interface ExceptionInterface extends Exception
+{}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Exception/InvalidArgumentException.php b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Exception/InvalidArgumentException.php
new file mode 100644
index 000000000000..0b2339f13103
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Exception/InvalidArgumentException.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\PubSubHubbub\Exception;
+
+use Zend\Feed\Exception;
+
+class InvalidArgumentException
+    extends Exception\InvalidArgumentException
+    implements ExceptionInterface
+{}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Exception/RuntimeException.php b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Exception/RuntimeException.php
new file mode 100644
index 000000000000..23e154411b7f
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Exception/RuntimeException.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\PubSubHubbub\Exception;
+
+use Zend\Feed\Exception;
+
+class RuntimeException
+    extends Exception\RuntimeException
+    implements ExceptionInterface
+{}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/HttpResponse.php b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/HttpResponse.php
new file mode 100644
index 000000000000..d820cf9f1436
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/HttpResponse.php
@@ -0,0 +1,211 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\PubSubHubbub;
+
+class HttpResponse
+{
+    /**
+     * The body of any response to the current callback request
+     *
+     * @var string
+     */
+    protected $content = '';
+
+    /**
+     * Array of headers. Each header is an array with keys 'name' and 'value'
+     *
+     * @var array
+     */
+    protected $headers = array();
+
+    /**
+     * HTTP response code to use in headers
+     *
+     * @var int
+     */
+    protected $statusCode = 200;
+
+    /**
+     * Send the response, including all headers
+     *
+     * @return void
+     */
+    public function send()
+    {
+        $this->sendHeaders();
+        echo $this->getContent();
+    }
+
+    /**
+     * Send all headers
+     *
+     * Sends any headers specified. If an {@link setHttpResponseCode() HTTP response code}
+     * has been specified, it is sent with the first header.
+     *
+     * @return void
+     */
+    public function sendHeaders()
+    {
+        if (count($this->headers) || (200 != $this->statusCode)) {
+            $this->canSendHeaders(true);
+        } elseif (200 == $this->statusCode) {
+            return;
+        }
+        $httpCodeSent = false;
+        foreach ($this->headers as $header) {
+            if (!$httpCodeSent && $this->statusCode) {
+                header($header['name'] . ': ' . $header['value'], $header['replace'], $this->statusCode);
+                $httpCodeSent = true;
+            } else {
+                header($header['name'] . ': ' . $header['value'], $header['replace']);
+            }
+        }
+        if (!$httpCodeSent) {
+            header('HTTP/1.1 ' . $this->statusCode);
+        }
+    }
+
+    /**
+     * Set a header
+     *
+     * If $replace is true, replaces any headers already defined with that
+     * $name.
+     *
+     * @param  string $name
+     * @param  string $value
+     * @param  bool $replace
+     * @return \Zend\Feed\PubSubHubbub\HttpResponse
+     */
+    public function setHeader($name, $value, $replace = false)
+    {
+        $name  = $this->_normalizeHeader($name);
+        $value = (string) $value;
+        if ($replace) {
+            foreach ($this->headers as $key => $header) {
+                if ($name == $header['name']) {
+                    unset($this->headers[$key]);
+                }
+            }
+        }
+        $this->headers[] = array(
+            'name'    => $name,
+            'value'   => $value,
+            'replace' => $replace,
+        );
+
+        return $this;
+    }
+
+    /**
+     * Check if a specific Header is set and return its value
+     *
+     * @param  string $name
+     * @return string|null
+     */
+    public function getHeader($name)
+    {
+        $name = $this->_normalizeHeader($name);
+        foreach ($this->headers as $header) {
+            if ($header['name'] == $name) {
+                return $header['value'];
+            }
+        }
+    }
+
+    /**
+     * Return array of headers; see {@link $headers} for format
+     *
+     * @return array
+     */
+    public function getHeaders()
+    {
+        return $this->headers;
+    }
+
+    /**
+     * Can we send headers?
+     *
+     * @param  bool $throw Whether or not to throw an exception if headers have been sent; defaults to false
+     * @return HttpResponse
+     * @throws Exception\RuntimeException
+     */
+    public function canSendHeaders($throw = false)
+    {
+        $ok = headers_sent($file, $line);
+        if ($ok && $throw) {
+            throw new Exception\RuntimeException('Cannot send headers; headers already sent in ' . $file . ', line ' . $line);
+        }
+        return !$ok;
+    }
+
+    /**
+     * Set HTTP response code to use with headers
+     *
+     * @param  int $code
+     * @return HttpResponse
+     * @throws Exception\InvalidArgumentException
+     */
+    public function setStatusCode($code)
+    {
+        if (!is_int($code) || (100 > $code) || (599 < $code)) {
+            throw new Exception\InvalidArgumentException('Invalid HTTP response'
+            . ' code:' . $code);
+        }
+        $this->statusCode = $code;
+        return $this;
+    }
+
+    /**
+     * Retrieve HTTP response code
+     *
+     * @return int
+     */
+    public function getStatusCode()
+    {
+        return $this->statusCode;
+    }
+
+    /**
+     * Set body content
+     *
+     * @param  string $content
+     * @return \Zend\Feed\PubSubHubbub\HttpResponse
+     */
+    public function setContent($content)
+    {
+        $this->content = (string) $content;
+        $this->setHeader('content-length', strlen($content));
+        return $this;
+    }
+
+    /**
+     * Return the body content
+     *
+     * @return string
+     */
+    public function getContent()
+    {
+        return $this->content;
+    }
+
+    /**
+     * Normalizes a header name to X-Capitalized-Names
+     *
+     * @param  string $name
+     * @return string
+     */
+    protected function _normalizeHeader($name)
+    {
+        $filtered = str_replace(array('-', '_'), ' ', (string) $name);
+        $filtered = ucwords(strtolower($filtered));
+        $filtered = str_replace(' ', '-', $filtered);
+        return $filtered;
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Model/AbstractModel.php b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Model/AbstractModel.php
new file mode 100644
index 000000000000..023fe8ed67d3
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Model/AbstractModel.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\PubSubHubbub\Model;
+
+use Zend\Db\TableGateway\TableGateway;
+use Zend\Db\TableGateway\TableGatewayInterface;
+
+class AbstractModel
+{
+    /**
+     * Zend\Db\TableGateway\TableGatewayInterface instance to host database methods
+     *
+     * @var TableGatewayInterface
+     */
+    protected $db = null;
+
+    /**
+     * Constructor
+     *
+     * @param null|TableGatewayInterface $tableGateway
+     */
+    public function __construct(TableGatewayInterface $tableGateway = null)
+    {
+        if ($tableGateway === null) {
+            $parts = explode('\\', get_class($this));
+            $table = strtolower(array_pop($parts));
+            $this->db = new TableGateway($table, null);
+        } else {
+            $this->db = $tableGateway;
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Model/Subscription.php b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Model/Subscription.php
new file mode 100644
index 000000000000..a7a4596b36b2
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Model/Subscription.php
@@ -0,0 +1,142 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\PubSubHubbub\Model;
+
+use DateInterval;
+use DateTime;
+use Zend\Feed\PubSubHubbub;
+
+class Subscription extends AbstractModel implements SubscriptionPersistenceInterface
+{
+    /**
+     * Common DateTime object to assist with unit testing
+     *
+     * @var DateTime
+     */
+    protected $now;
+
+    /**
+     * Save subscription to RDMBS
+     *
+     * @param array $data
+     * @return bool
+     * @throws PubSubHubbub\Exception\InvalidArgumentException
+     */
+    public function setSubscription(array $data)
+    {
+        if (!isset($data['id'])) {
+            throw new PubSubHubbub\Exception\InvalidArgumentException(
+                'ID must be set before attempting a save'
+            );
+        }
+        $result = $this->db->select(array('id' => $data['id']));
+        if ($result && (0 < count($result))) {
+            $data['created_time'] = $result->current()->created_time;
+            $now = $this->getNow();
+            if (array_key_exists('lease_seconds', $data)
+                && $data['lease_seconds']
+            ) {
+                $data['expiration_time'] = $now->add(new DateInterval('PT' . $data['lease_seconds'] . 'S'))
+                    ->format('Y-m-d H:i:s');
+            }
+            $this->db->update(
+                $data,
+                array('id' => $data['id'])
+            );
+            return false;
+        }
+
+        $this->db->insert($data);
+        return true;
+    }
+
+    /**
+     * Get subscription by ID/key
+     *
+     * @param  string $key
+     * @return array
+     * @throws PubSubHubbub\Exception\InvalidArgumentException
+     */
+    public function getSubscription($key)
+    {
+        if (empty($key) || !is_string($key)) {
+            throw new PubSubHubbub\Exception\InvalidArgumentException('Invalid parameter "key"'
+                .' of "' . $key . '" must be a non-empty string');
+        }
+        $result = $this->db->select(array('id' => $key));
+        if (count($result)) {
+            return $result->current()->getArrayCopy();
+        }
+        return false;
+    }
+
+    /**
+     * Determine if a subscription matching the key exists
+     *
+     * @param  string $key
+     * @return bool
+     * @throws PubSubHubbub\Exception\InvalidArgumentException
+     */
+    public function hasSubscription($key)
+    {
+        if (empty($key) || !is_string($key)) {
+            throw new PubSubHubbub\Exception\InvalidArgumentException('Invalid parameter "key"'
+                .' of "' . $key . '" must be a non-empty string');
+        }
+        $result = $this->db->select(array('id' => $key));
+        if (count($result)) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Delete a subscription
+     *
+     * @param string $key
+     * @return bool
+     */
+    public function deleteSubscription($key)
+    {
+        $result = $this->db->select(array('id' => $key));
+        if (count($result)) {
+            $this->db->delete(
+                array('id' => $key)
+            );
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Get a new DateTime or the one injected for testing
+     *
+     * @return DateTime
+     */
+    public function getNow()
+    {
+        if (null === $this->now) {
+            return new DateTime();
+        }
+        return $this->now;
+    }
+
+    /**
+     * Set a DateTime instance for assisting with unit testing
+     *
+     * @param DateTime $now
+     * @return Subscription
+     */
+    public function setNow(DateTime $now)
+    {
+        $this->now = $now;
+        return $this;
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Model/SubscriptionPersistenceInterface.php b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Model/SubscriptionPersistenceInterface.php
new file mode 100644
index 000000000000..717591b0fc1a
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Model/SubscriptionPersistenceInterface.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\PubSubHubbub\Model;
+
+interface SubscriptionPersistenceInterface
+{
+
+    /**
+     * Save subscription to RDMBS
+     *
+     * @param array $data The key must be stored here as a $data['id'] entry
+     * @return bool
+     */
+    public function setSubscription(array $data);
+
+    /**
+     * Get subscription by ID/key
+     *
+     * @param  string $key
+     * @return array
+     */
+    public function getSubscription($key);
+
+    /**
+     * Determine if a subscription matching the key exists
+     *
+     * @param  string $key
+     * @return bool
+     */
+    public function hasSubscription($key);
+
+    /**
+     * Delete a subscription
+     *
+     * @param string $key
+     * @return bool
+     */
+    public function deleteSubscription($key);
+
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/PubSubHubbub.php b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/PubSubHubbub.php
new file mode 100644
index 000000000000..ee009801e1f6
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/PubSubHubbub.php
@@ -0,0 +1,147 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\PubSubHubbub;
+
+use Zend\Escaper\Escaper;
+use Zend\Feed\Reader;
+use Zend\Http;
+
+class PubSubHubbub
+{
+    /**
+     * Verification Modes
+     */
+    const VERIFICATION_MODE_SYNC  = 'sync';
+    const VERIFICATION_MODE_ASYNC = 'async';
+
+    /**
+     * Subscription States
+     */
+    const SUBSCRIPTION_VERIFIED    = 'verified';
+    const SUBSCRIPTION_NOTVERIFIED = 'not_verified';
+    const SUBSCRIPTION_TODELETE    = 'to_delete';
+
+    /**
+     * @var Escaper
+     */
+    protected static $escaper;
+
+    /**
+     * Singleton instance if required of the HTTP client
+     *
+     * @var Http\Client
+     */
+    protected static $httpClient = null;
+
+    /**
+     * Simple utility function which imports any feed URL and
+     * determines the existence of Hub Server endpoints. This works
+     * best if directly given an instance of Zend\Feed\Reader\Atom|Rss
+     * to leverage off.
+     *
+     * @param  \Zend\Feed\Reader\Feed\AbstractFeed|string $source
+     * @return array
+     * @throws Exception\InvalidArgumentException
+     */
+    public static function detectHubs($source)
+    {
+        if (is_string($source)) {
+            $feed = Reader\Reader::import($source);
+        } elseif ($source instanceof Reader\Feed\AbstractFeed) {
+            $feed = $source;
+        } else {
+            throw new Exception\InvalidArgumentException('The source parameter was'
+            . ' invalid, i.e. not a URL string or an instance of type'
+            . ' Zend\Feed\Reader\Feed\AbstractFeed');
+        }
+        return $feed->getHubs();
+    }
+
+    /**
+     * Allows the external environment to make Oauth use a specific
+     * Client instance.
+     *
+     * @param  Http\Client $httpClient
+     * @return void
+     */
+    public static function setHttpClient(Http\Client $httpClient)
+    {
+        static::$httpClient = $httpClient;
+    }
+
+    /**
+     * Return the singleton instance of the HTTP Client. Note that
+     * the instance is reset and cleared of previous parameters GET/POST.
+     * Headers are NOT reset but handled by this component if applicable.
+     *
+     * @return Http\Client
+     */
+    public static function getHttpClient()
+    {
+        if (!isset(static::$httpClient)) {
+            static::$httpClient = new Http\Client;
+        } else {
+            static::$httpClient->resetParameters();
+        }
+        return static::$httpClient;
+    }
+
+    /**
+     * Simple mechanism to delete the entire singleton HTTP Client instance
+     * which forces an new instantiation for subsequent requests.
+     *
+     * @return void
+     */
+    public static function clearHttpClient()
+    {
+        static::$httpClient = null;
+    }
+
+    /**
+     * Set the Escaper instance
+     *
+     * If null, resets the instance
+     *
+     * @param  null|Escaper $escaper
+     */
+    public static function setEscaper(Escaper $escaper = null)
+    {
+        static::$escaper = $escaper;
+    }
+
+    /**
+     * Get the Escaper instance
+     *
+     * If none registered, lazy-loads an instance.
+     *
+     * @return Escaper
+     */
+    public static function getEscaper()
+    {
+        if (null === static::$escaper) {
+            static::setEscaper(new Escaper());
+        }
+        return static::$escaper;
+    }
+
+    /**
+     * RFC 3986 safe url encoding method
+     *
+     * @param  string $string
+     * @return string
+     */
+    public static function urlencode($string)
+    {
+        $escaper    = static::getEscaper();
+        $rawencoded = $escaper->escapeUrl($string);
+        $rfcencoded = str_replace('%7E', '~', $rawencoded);
+        return $rfcencoded;
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Publisher.php b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Publisher.php
new file mode 100644
index 000000000000..ec9c4e1ea8fb
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Publisher.php
@@ -0,0 +1,397 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\PubSubHubbub;
+
+use Traversable;
+use Zend\Feed\Uri;
+use Zend\Http\Request as HttpRequest;
+use Zend\Stdlib\ArrayUtils;
+
+class Publisher
+{
+    /**
+     * An array of URLs for all Hub Servers used by the Publisher, and to
+     * which all topic update notifications will be sent.
+     *
+     * @var array
+     */
+    protected $hubUrls = array();
+
+    /**
+     * An array of topic (Atom or RSS feed) URLs which have been updated and
+     * whose updated status will be notified to all Hub Servers.
+     *
+     * @var array
+     */
+    protected $updatedTopicUrls = array();
+
+    /**
+     * An array of any errors including keys for 'response', 'hubUrl'.
+     * The response is the actual Zend\Http\Response object.
+     *
+     * @var array
+     */
+    protected $errors = array();
+
+    /**
+     * An array of topic (Atom or RSS feed) URLs which have been updated and
+     * whose updated status will be notified to all Hub Servers.
+     *
+     * @var array
+     */
+    protected $parameters = array();
+
+    /**
+     * Constructor; accepts an array or Zend\Config instance to preset
+     * options for the Publisher without calling all supported setter
+     * methods in turn.
+     *
+     * @param  array|Traversable $options
+     */
+    public function __construct($options = null)
+    {
+        if ($options !== null) {
+            $this->setOptions($options);
+        }
+    }
+
+    /**
+     * Process any injected configuration options
+     *
+     * @param  array|Traversable $options Options array or Traversable object
+     * @return Publisher
+     * @throws Exception\InvalidArgumentException
+     */
+    public function setOptions($options)
+    {
+        if ($options instanceof Traversable) {
+            $options = ArrayUtils::iteratorToArray($options);
+        }
+
+        if (!is_array($options)) {
+            throw new Exception\InvalidArgumentException('Array or Traversable object'
+                                . 'expected, got ' . gettype($options));
+        }
+        if (array_key_exists('hubUrls', $options)) {
+            $this->addHubUrls($options['hubUrls']);
+        }
+        if (array_key_exists('updatedTopicUrls', $options)) {
+            $this->addUpdatedTopicUrls($options['updatedTopicUrls']);
+        }
+        if (array_key_exists('parameters', $options)) {
+            $this->setParameters($options['parameters']);
+        }
+        return $this;
+    }
+
+    /**
+     * Add a Hub Server URL supported by Publisher
+     *
+     * @param  string $url
+     * @return Publisher
+     * @throws Exception\InvalidArgumentException
+     */
+    public function addHubUrl($url)
+    {
+        if (empty($url) || !is_string($url) || !Uri::factory($url)->isValid()) {
+            throw new Exception\InvalidArgumentException('Invalid parameter "url"'
+                . ' of "' . $url . '" must be a non-empty string and a valid'
+                . 'URL');
+        }
+        $this->hubUrls[] = $url;
+        return $this;
+    }
+
+    /**
+     * Add an array of Hub Server URLs supported by Publisher
+     *
+     * @param  array $urls
+     * @return Publisher
+     */
+    public function addHubUrls(array $urls)
+    {
+        foreach ($urls as $url) {
+            $this->addHubUrl($url);
+        }
+        return $this;
+    }
+
+    /**
+     * Remove a Hub Server URL
+     *
+     * @param  string $url
+     * @return Publisher
+     */
+    public function removeHubUrl($url)
+    {
+        if (!in_array($url, $this->getHubUrls())) {
+            return $this;
+        }
+        $key = array_search($url, $this->hubUrls);
+        unset($this->hubUrls[$key]);
+        return $this;
+    }
+
+    /**
+     * Return an array of unique Hub Server URLs currently available
+     *
+     * @return array
+     */
+    public function getHubUrls()
+    {
+        $this->hubUrls = array_unique($this->hubUrls);
+        return $this->hubUrls;
+    }
+
+    /**
+     * Add a URL to a topic (Atom or RSS feed) which has been updated
+     *
+     * @param  string $url
+     * @return Publisher
+     * @throws Exception\InvalidArgumentException
+     */
+    public function addUpdatedTopicUrl($url)
+    {
+        if (empty($url) || !is_string($url) || !Uri::factory($url)->isValid()) {
+            throw new Exception\InvalidArgumentException('Invalid parameter "url"'
+                . ' of "' . $url . '" must be a non-empty string and a valid'
+                . 'URL');
+        }
+        $this->updatedTopicUrls[] = $url;
+        return $this;
+    }
+
+    /**
+     * Add an array of Topic URLs which have been updated
+     *
+     * @param  array $urls
+     * @return Publisher
+     */
+    public function addUpdatedTopicUrls(array $urls)
+    {
+        foreach ($urls as $url) {
+            $this->addUpdatedTopicUrl($url);
+        }
+        return $this;
+    }
+
+    /**
+     * Remove an updated topic URL
+     *
+     * @param  string $url
+     * @return Publisher
+     */
+    public function removeUpdatedTopicUrl($url)
+    {
+        if (!in_array($url, $this->getUpdatedTopicUrls())) {
+            return $this;
+        }
+        $key = array_search($url, $this->updatedTopicUrls);
+        unset($this->updatedTopicUrls[$key]);
+        return $this;
+    }
+
+    /**
+     * Return an array of unique updated topic URLs currently available
+     *
+     * @return array
+     */
+    public function getUpdatedTopicUrls()
+    {
+        $this->updatedTopicUrls = array_unique($this->updatedTopicUrls);
+        return $this->updatedTopicUrls;
+    }
+
+    /**
+     * Notifies a single Hub Server URL of changes
+     *
+     * @param  string $url The Hub Server's URL
+     * @return void
+     * @throws Exception\InvalidArgumentException
+     * @throws Exception\RuntimeException
+     */
+    public function notifyHub($url)
+    {
+        if (empty($url) || !is_string($url) || !Uri::factory($url)->isValid()) {
+            throw new Exception\InvalidArgumentException('Invalid parameter "url"'
+                . ' of "' . $url . '" must be a non-empty string and a valid'
+                . 'URL');
+        }
+        $client = $this->_getHttpClient();
+        $client->setUri($url);
+        $response = $client->getResponse();
+        if ($response->getStatusCode() !== 204) {
+            throw new Exception\RuntimeException('Notification to Hub Server '
+                . 'at "' . $url . '" appears to have failed with a status code of "'
+                . $response->getStatusCode() . '" and message "'
+                . $response->getContent() . '"');
+        }
+    }
+
+    /**
+     * Notifies all Hub Server URLs of changes
+     *
+     * If a Hub notification fails, certain data will be retained in an
+     * an array retrieved using getErrors(), if a failure occurs for any Hubs
+     * the isSuccess() check will return FALSE. This method is designed not
+     * to needlessly fail with an Exception/Error unless from Zend\Http\Client.
+     *
+     * @return void
+     * @throws Exception\RuntimeException
+     */
+    public function notifyAll()
+    {
+        $client = $this->_getHttpClient();
+        $hubs   = $this->getHubUrls();
+        if (empty($hubs)) {
+            throw new Exception\RuntimeException('No Hub Server URLs'
+                . ' have been set so no notifications can be sent');
+        }
+        $this->errors = array();
+        foreach ($hubs as $url) {
+            $client->setUri($url);
+            $response = $client->getResponse();
+            if ($response->getStatusCode() !== 204) {
+                $this->errors[] = array(
+                    'response' => $response,
+                    'hubUrl' => $url
+                );
+            }
+        }
+    }
+
+    /**
+     * Add an optional parameter to the update notification requests
+     *
+     * @param  string $name
+     * @param  string|null $value
+     * @return Publisher
+     * @throws Exception\InvalidArgumentException
+     */
+    public function setParameter($name, $value = null)
+    {
+        if (is_array($name)) {
+            $this->setParameters($name);
+            return $this;
+        }
+        if (empty($name) || !is_string($name)) {
+            throw new Exception\InvalidArgumentException('Invalid parameter "name"'
+                . ' of "' . $name . '" must be a non-empty string');
+        }
+        if ($value === null) {
+            $this->removeParameter($name);
+            return $this;
+        }
+        if (empty($value) || (!is_string($value) && $value !== null)) {
+            throw new Exception\InvalidArgumentException('Invalid parameter "value"'
+                . ' of "' . $value . '" must be a non-empty string');
+        }
+        $this->parameters[$name] = $value;
+        return $this;
+    }
+
+    /**
+     * Add an optional parameter to the update notification requests
+     *
+     * @param  array $parameters
+     * @return Publisher
+     */
+    public function setParameters(array $parameters)
+    {
+        foreach ($parameters as $name => $value) {
+            $this->setParameter($name, $value);
+        }
+        return $this;
+    }
+
+    /**
+     * Remove an optional parameter for the notification requests
+     *
+     * @param  string $name
+     * @return Publisher
+     * @throws Exception\InvalidArgumentException
+     */
+    public function removeParameter($name)
+    {
+        if (empty($name) || !is_string($name)) {
+            throw new Exception\InvalidArgumentException('Invalid parameter "name"'
+                . ' of "' . $name . '" must be a non-empty string');
+        }
+        if (array_key_exists($name, $this->parameters)) {
+            unset($this->parameters[$name]);
+        }
+        return $this;
+    }
+
+    /**
+     * Return an array of optional parameters for notification requests
+     *
+     * @return array
+     */
+    public function getParameters()
+    {
+        return $this->parameters;
+    }
+
+    /**
+     * Returns a boolean indicator of whether the notifications to Hub
+     * Servers were ALL successful. If even one failed, FALSE is returned.
+     *
+     * @return bool
+     */
+    public function isSuccess()
+    {
+        return !(count($this->errors) != 0);
+    }
+
+    /**
+     * Return an array of errors met from any failures, including keys:
+     * 'response' => the Zend\Http\Response object from the failure
+     * 'hubUrl' => the URL of the Hub Server whose notification failed
+     *
+     * @return array
+     */
+    public function getErrors()
+    {
+        return $this->errors;
+    }
+
+    /**
+     * Get a basic prepared HTTP client for use
+     *
+     * @return \Zend\Http\Client
+     * @throws Exception\RuntimeException
+     */
+    protected function _getHttpClient()
+    {
+        $client = PubSubHubbub::getHttpClient();
+        $client->setMethod(HttpRequest::METHOD_POST);
+        $client->setOptions(array(
+            'useragent' => 'Zend_Feed_Pubsubhubbub_Publisher/' . Version::VERSION,
+        ));
+        $params   = array();
+        $params[] = 'hub.mode=publish';
+        $topics   = $this->getUpdatedTopicUrls();
+        if (empty($topics)) {
+            throw new Exception\RuntimeException('No updated topic URLs'
+                . ' have been set');
+        }
+        foreach ($topics as $topicUrl) {
+            $params[] = 'hub.url=' . urlencode($topicUrl);
+        }
+        $optParams = $this->getParameters();
+        foreach ($optParams as $name => $value) {
+            $params[] = urlencode($name) . '=' . urlencode($value);
+        }
+        $paramString = implode('&', $params);
+        $client->setRawBody($paramString);
+        return $client;
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Subscriber.php b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Subscriber.php
new file mode 100644
index 000000000000..7171694d20a4
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Subscriber.php
@@ -0,0 +1,837 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\PubSubHubbub;
+
+use DateInterval;
+use DateTime;
+use Traversable;
+use Zend\Feed\Uri;
+use Zend\Http\Request as HttpRequest;
+use Zend\Stdlib\ArrayUtils;
+
+class Subscriber
+{
+    /**
+     * An array of URLs for all Hub Servers to subscribe/unsubscribe.
+     *
+     * @var array
+     */
+    protected $hubUrls = array();
+
+    /**
+     * An array of optional parameters to be included in any
+     * (un)subscribe requests.
+     *
+     * @var array
+     */
+    protected $parameters = array();
+
+    /**
+     * The URL of the topic (Rss or Atom feed) which is the subject of
+     * our current intent to subscribe to/unsubscribe from updates from
+     * the currently configured Hub Servers.
+     *
+     * @var string
+     */
+    protected $topicUrl = '';
+
+    /**
+     * The URL Hub Servers must use when communicating with this Subscriber
+     *
+     * @var string
+     */
+    protected $callbackUrl = '';
+
+    /**
+     * The number of seconds for which the subscriber would like to have the
+     * subscription active. Defaults to null, i.e. not sent, to setup a
+     * permanent subscription if possible.
+     *
+     * @var int
+     */
+    protected $leaseSeconds = null;
+
+    /**
+     * The preferred verification mode (sync or async). By default, this
+     * Subscriber prefers synchronous verification, but is considered
+     * desirable to support asynchronous verification if possible.
+     *
+     * Zend\Feed\Pubsubhubbub\Subscriber will always send both modes, whose
+     * order of occurrence in the parameter list determines this preference.
+     *
+     * @var string
+     */
+    protected $preferredVerificationMode = PubSubHubbub::VERIFICATION_MODE_SYNC;
+
+    /**
+     * An array of any errors including keys for 'response', 'hubUrl'.
+     * The response is the actual Zend\Http\Response object.
+     *
+     * @var array
+     */
+    protected $errors = array();
+
+    /**
+     * An array of Hub Server URLs for Hubs operating at this time in
+     * asynchronous verification mode.
+     *
+     * @var array
+     */
+    protected $asyncHubs = array();
+
+    /**
+     * An instance of Zend\Feed\Pubsubhubbub\Model\SubscriptionPersistence used to background
+     * save any verification tokens associated with a subscription or other.
+     *
+     * @var \Zend\Feed\PubSubHubbub\Model\SubscriptionPersistenceInterface
+     */
+    protected $storage = null;
+
+    /**
+     * An array of authentication credentials for HTTP Basic Authentication
+     * if required by specific Hubs. The array is indexed by Hub Endpoint URI
+     * and the value is a simple array of the username and password to apply.
+     *
+     * @var array
+     */
+    protected $authentications = array();
+
+    /**
+     * Tells the Subscriber to append any subscription identifier to the path
+     * of the base Callback URL. E.g. an identifier "subkey1" would be added
+     * to the callback URL "http://www.example.com/callback" to create a subscription
+     * specific Callback URL of "http://www.example.com/callback/subkey1".
+     *
+     * This is required for all Hubs using the Pubsubhubbub 0.1 Specification.
+     * It should be manually intercepted and passed to the Callback class using
+     * Zend\Feed\Pubsubhubbub\Subscriber\Callback::setSubscriptionKey(). Will
+     * require a route in the form "callback/:subkey" to allow the parameter be
+     * retrieved from an action using the Zend\Controller\Action::\getParam()
+     * method.
+     *
+     * @var string
+     */
+    protected $usePathParameter = false;
+
+    /**
+     * Constructor; accepts an array or Traversable instance to preset
+     * options for the Subscriber without calling all supported setter
+     * methods in turn.
+     *
+     * @param  array|Traversable $options
+     */
+    public function __construct($options = null)
+    {
+        if ($options !== null) {
+            $this->setOptions($options);
+        }
+    }
+
+    /**
+     * Process any injected configuration options
+     *
+     * @param  array|Traversable $options
+     * @return Subscriber
+     * @throws Exception\InvalidArgumentException
+     */
+    public function setOptions($options)
+    {
+        if ($options instanceof Traversable) {
+            $options = ArrayUtils::iteratorToArray($options);
+        }
+
+        if (!is_array($options)) {
+            throw new Exception\InvalidArgumentException('Array or Traversable object'
+                                . 'expected, got ' . gettype($options));
+        }
+        if (array_key_exists('hubUrls', $options)) {
+            $this->addHubUrls($options['hubUrls']);
+        }
+        if (array_key_exists('callbackUrl', $options)) {
+            $this->setCallbackUrl($options['callbackUrl']);
+        }
+        if (array_key_exists('topicUrl', $options)) {
+            $this->setTopicUrl($options['topicUrl']);
+        }
+        if (array_key_exists('storage', $options)) {
+            $this->setStorage($options['storage']);
+        }
+        if (array_key_exists('leaseSeconds', $options)) {
+            $this->setLeaseSeconds($options['leaseSeconds']);
+        }
+        if (array_key_exists('parameters', $options)) {
+            $this->setParameters($options['parameters']);
+        }
+        if (array_key_exists('authentications', $options)) {
+            $this->addAuthentications($options['authentications']);
+        }
+        if (array_key_exists('usePathParameter', $options)) {
+            $this->usePathParameter($options['usePathParameter']);
+        }
+        if (array_key_exists('preferredVerificationMode', $options)) {
+            $this->setPreferredVerificationMode(
+                $options['preferredVerificationMode']
+            );
+        }
+        return $this;
+    }
+
+    /**
+     * Set the topic URL (RSS or Atom feed) to which the intended (un)subscribe
+     * event will relate
+     *
+     * @param  string $url
+     * @return Subscriber
+     * @throws Exception\InvalidArgumentException
+     */
+    public function setTopicUrl($url)
+    {
+        if (empty($url) || !is_string($url) || !Uri::factory($url)->isValid()) {
+            throw new Exception\InvalidArgumentException('Invalid parameter "url"'
+                .' of "' . $url . '" must be a non-empty string and a valid'
+                .' URL');
+        }
+        $this->topicUrl = $url;
+        return $this;
+    }
+
+    /**
+     * Set the topic URL (RSS or Atom feed) to which the intended (un)subscribe
+     * event will relate
+     *
+     * @return string
+     * @throws Exception\RuntimeException
+     */
+    public function getTopicUrl()
+    {
+        if (empty($this->topicUrl)) {
+            throw new Exception\RuntimeException('A valid Topic (RSS or Atom'
+                . ' feed) URL MUST be set before attempting any operation');
+        }
+        return $this->topicUrl;
+    }
+
+    /**
+     * Set the number of seconds for which any subscription will remain valid
+     *
+     * @param  int $seconds
+     * @return Subscriber
+     * @throws Exception\InvalidArgumentException
+     */
+    public function setLeaseSeconds($seconds)
+    {
+        $seconds = intval($seconds);
+        if ($seconds <= 0) {
+            throw new Exception\InvalidArgumentException('Expected lease seconds'
+                . ' must be an integer greater than zero');
+        }
+        $this->leaseSeconds = $seconds;
+        return $this;
+    }
+
+    /**
+     * Get the number of lease seconds on subscriptions
+     *
+     * @return int
+     */
+    public function getLeaseSeconds()
+    {
+        return $this->leaseSeconds;
+    }
+
+    /**
+     * Set the callback URL to be used by Hub Servers when communicating with
+     * this Subscriber
+     *
+     * @param  string $url
+     * @return Subscriber
+     * @throws Exception\InvalidArgumentException
+     */
+    public function setCallbackUrl($url)
+    {
+        if (empty($url) || !is_string($url) || !Uri::factory($url)->isValid()) {
+            throw new Exception\InvalidArgumentException('Invalid parameter "url"'
+                . ' of "' . $url . '" must be a non-empty string and a valid'
+                . ' URL');
+        }
+        $this->callbackUrl = $url;
+        return $this;
+    }
+
+    /**
+     * Get the callback URL to be used by Hub Servers when communicating with
+     * this Subscriber
+     *
+     * @return string
+     * @throws Exception\RuntimeException
+     */
+    public function getCallbackUrl()
+    {
+        if (empty($this->callbackUrl)) {
+            throw new Exception\RuntimeException('A valid Callback URL MUST be'
+                . ' set before attempting any operation');
+        }
+        return $this->callbackUrl;
+    }
+
+    /**
+     * Set preferred verification mode (sync or async). By default, this
+     * Subscriber prefers synchronous verification, but does support
+     * asynchronous if that's the Hub Server's utilised mode.
+     *
+     * Zend\Feed\Pubsubhubbub\Subscriber will always send both modes, whose
+     * order of occurrence in the parameter list determines this preference.
+     *
+     * @param  string $mode Should be 'sync' or 'async'
+     * @return Subscriber
+     * @throws Exception\InvalidArgumentException
+     */
+    public function setPreferredVerificationMode($mode)
+    {
+        if ($mode !== PubSubHubbub::VERIFICATION_MODE_SYNC
+            && $mode !== PubSubHubbub::VERIFICATION_MODE_ASYNC
+        ) {
+            throw new Exception\InvalidArgumentException('Invalid preferred'
+                . ' mode specified: "' . $mode . '" but should be one of'
+                . ' Zend\Feed\Pubsubhubbub::VERIFICATION_MODE_SYNC or'
+                . ' Zend\Feed\Pubsubhubbub::VERIFICATION_MODE_ASYNC');
+        }
+        $this->preferredVerificationMode = $mode;
+        return $this;
+    }
+
+    /**
+     * Get preferred verification mode (sync or async).
+     *
+     * @return string
+     */
+    public function getPreferredVerificationMode()
+    {
+        return $this->preferredVerificationMode;
+    }
+
+    /**
+     * Add a Hub Server URL supported by Publisher
+     *
+     * @param  string $url
+     * @return Subscriber
+     * @throws Exception\InvalidArgumentException
+     */
+    public function addHubUrl($url)
+    {
+        if (empty($url) || !is_string($url) || !Uri::factory($url)->isValid()) {
+            throw new Exception\InvalidArgumentException('Invalid parameter "url"'
+                . ' of "' . $url . '" must be a non-empty string and a valid'
+                . ' URL');
+        }
+        $this->hubUrls[] = $url;
+        return $this;
+    }
+
+    /**
+     * Add an array of Hub Server URLs supported by Publisher
+     *
+     * @param  array $urls
+     * @return Subscriber
+     */
+    public function addHubUrls(array $urls)
+    {
+        foreach ($urls as $url) {
+            $this->addHubUrl($url);
+        }
+        return $this;
+    }
+
+    /**
+     * Remove a Hub Server URL
+     *
+     * @param  string $url
+     * @return Subscriber
+     */
+    public function removeHubUrl($url)
+    {
+        if (!in_array($url, $this->getHubUrls())) {
+            return $this;
+        }
+        $key = array_search($url, $this->hubUrls);
+        unset($this->hubUrls[$key]);
+        return $this;
+    }
+
+    /**
+     * Return an array of unique Hub Server URLs currently available
+     *
+     * @return array
+     */
+    public function getHubUrls()
+    {
+        $this->hubUrls = array_unique($this->hubUrls);
+        return $this->hubUrls;
+    }
+
+    /**
+     * Add authentication credentials for a given URL
+     *
+     * @param  string $url
+     * @param  array $authentication
+     * @return Subscriber
+     * @throws Exception\InvalidArgumentException
+     */
+    public function addAuthentication($url, array $authentication)
+    {
+        if (empty($url) || !is_string($url) || !Uri::factory($url)->isValid()) {
+            throw new Exception\InvalidArgumentException('Invalid parameter "url"'
+                . ' of "' . $url . '" must be a non-empty string and a valid'
+                . ' URL');
+        }
+        $this->authentications[$url] = $authentication;
+        return $this;
+    }
+
+    /**
+     * Add authentication credentials for hub URLs
+     *
+     * @param  array $authentications
+     * @return Subscriber
+     */
+    public function addAuthentications(array $authentications)
+    {
+        foreach ($authentications as $url => $authentication) {
+            $this->addAuthentication($url, $authentication);
+        }
+        return $this;
+    }
+
+    /**
+     * Get all hub URL authentication credentials
+     *
+     * @return array
+     */
+    public function getAuthentications()
+    {
+        return $this->authentications;
+    }
+
+    /**
+     * Set flag indicating whether or not to use a path parameter
+     *
+     * @param  bool $bool
+     * @return Subscriber
+     */
+    public function usePathParameter($bool = true)
+    {
+        $this->usePathParameter = $bool;
+        return $this;
+    }
+
+    /**
+     * Add an optional parameter to the (un)subscribe requests
+     *
+     * @param  string $name
+     * @param  string|null $value
+     * @return Subscriber
+     * @throws Exception\InvalidArgumentException
+     */
+    public function setParameter($name, $value = null)
+    {
+        if (is_array($name)) {
+            $this->setParameters($name);
+            return $this;
+        }
+        if (empty($name) || !is_string($name)) {
+            throw new Exception\InvalidArgumentException('Invalid parameter "name"'
+                . ' of "' . $name . '" must be a non-empty string');
+        }
+        if ($value === null) {
+            $this->removeParameter($name);
+            return $this;
+        }
+        if (empty($value) || (!is_string($value) && $value !== null)) {
+            throw new Exception\InvalidArgumentException('Invalid parameter "value"'
+                . ' of "' . $value . '" must be a non-empty string');
+        }
+        $this->parameters[$name] = $value;
+        return $this;
+    }
+
+    /**
+     * Add an optional parameter to the (un)subscribe requests
+     *
+     * @param  array $parameters
+     * @return Subscriber
+     */
+    public function setParameters(array $parameters)
+    {
+        foreach ($parameters as $name => $value) {
+            $this->setParameter($name, $value);
+        }
+        return $this;
+    }
+
+    /**
+     * Remove an optional parameter for the (un)subscribe requests
+     *
+     * @param  string $name
+     * @return Subscriber
+     * @throws Exception\InvalidArgumentException
+     */
+    public function removeParameter($name)
+    {
+        if (empty($name) || !is_string($name)) {
+            throw new Exception\InvalidArgumentException('Invalid parameter "name"'
+                . ' of "' . $name . '" must be a non-empty string');
+        }
+        if (array_key_exists($name, $this->parameters)) {
+            unset($this->parameters[$name]);
+        }
+        return $this;
+    }
+
+    /**
+     * Return an array of optional parameters for (un)subscribe requests
+     *
+     * @return array
+     */
+    public function getParameters()
+    {
+        return $this->parameters;
+    }
+
+    /**
+     * Sets an instance of Zend\Feed\Pubsubhubbub\Model\SubscriptionPersistence used to background
+     * save any verification tokens associated with a subscription or other.
+     *
+     * @param  Model\SubscriptionPersistenceInterface $storage
+     * @return Subscriber
+     */
+    public function setStorage(Model\SubscriptionPersistenceInterface $storage)
+    {
+        $this->storage = $storage;
+        return $this;
+    }
+
+    /**
+     * Gets an instance of Zend\Feed\Pubsubhubbub\Storage\StoragePersistence used
+     * to background save any verification tokens associated with a subscription
+     * or other.
+     *
+     * @return Model\SubscriptionPersistenceInterface
+     * @throws Exception\RuntimeException
+     */
+    public function getStorage()
+    {
+        if ($this->storage === null) {
+            throw new Exception\RuntimeException('No storage vehicle '
+                . 'has been set.');
+        }
+        return $this->storage;
+    }
+
+    /**
+     * Subscribe to one or more Hub Servers using the stored Hub URLs
+     * for the given Topic URL (RSS or Atom feed)
+     *
+     * @return void
+     */
+    public function subscribeAll()
+    {
+        $this->_doRequest('subscribe');
+    }
+
+    /**
+     * Unsubscribe from one or more Hub Servers using the stored Hub URLs
+     * for the given Topic URL (RSS or Atom feed)
+     *
+     * @return void
+     */
+    public function unsubscribeAll()
+    {
+        $this->_doRequest('unsubscribe');
+    }
+
+    /**
+     * Returns a boolean indicator of whether the notifications to Hub
+     * Servers were ALL successful. If even one failed, FALSE is returned.
+     *
+     * @return bool
+     */
+    public function isSuccess()
+    {
+        if (count($this->errors) > 0) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Return an array of errors met from any failures, including keys:
+     * 'response' => the Zend\Http\Response object from the failure
+     * 'hubUrl' => the URL of the Hub Server whose notification failed
+     *
+     * @return array
+     */
+    public function getErrors()
+    {
+        return $this->errors;
+    }
+
+    /**
+     * Return an array of Hub Server URLs who returned a response indicating
+     * operation in Asynchronous Verification Mode, i.e. they will not confirm
+     * any (un)subscription immediately but at a later time (Hubs may be
+     * doing this as a batch process when load balancing)
+     *
+     * @return array
+     */
+    public function getAsyncHubs()
+    {
+        return $this->asyncHubs;
+    }
+
+    /**
+     * Executes an (un)subscribe request
+     *
+     * @param  string $mode
+     * @return void
+     * @throws Exception\RuntimeException
+     */
+    protected function _doRequest($mode)
+    {
+        $client = $this->_getHttpClient();
+        $hubs   = $this->getHubUrls();
+        if (empty($hubs)) {
+            throw new Exception\RuntimeException('No Hub Server URLs'
+                . ' have been set so no subscriptions can be attempted');
+        }
+        $this->errors = array();
+        $this->asyncHubs = array();
+        foreach ($hubs as $url) {
+            if (array_key_exists($url, $this->authentications)) {
+                $auth = $this->authentications[$url];
+                $client->setAuth($auth[0], $auth[1]);
+            }
+            $client->setUri($url);
+            $client->setRawBody($params = $this->_getRequestParameters($url, $mode));
+            $response = $client->send();
+            if ($response->getStatusCode() !== 204
+                && $response->getStatusCode() !== 202
+            ) {
+                $this->errors[] = array(
+                    'response' => $response,
+                    'hubUrl'   => $url,
+                );
+            /**
+             * At first I thought it was needed, but the backend storage will
+             * allow tracking async without any user interference. It's left
+             * here in case the user is interested in knowing what Hubs
+             * are using async verification modes so they may update Models and
+             * move these to asynchronous processes.
+             */
+            } elseif ($response->getStatusCode() == 202) {
+                $this->asyncHubs[] = array(
+                    'response' => $response,
+                    'hubUrl'   => $url,
+                );
+            }
+        }
+    }
+
+    /**
+     * Get a basic prepared HTTP client for use
+     *
+     * @return \Zend\Http\Client
+     */
+    protected function _getHttpClient()
+    {
+        $client = PubSubHubbub::getHttpClient();
+        $client->setMethod(HttpRequest::METHOD_POST);
+        $client->setOptions(array('useragent' => 'Zend_Feed_Pubsubhubbub_Subscriber/'
+            . Version::VERSION));
+        return $client;
+    }
+
+    /**
+     * Return a list of standard protocol/optional parameters for addition to
+     * client's POST body that are specific to the current Hub Server URL
+     *
+     * @param  string $hubUrl
+     * @param  string $mode
+     * @return string
+     * @throws Exception\InvalidArgumentException
+     */
+    protected function _getRequestParameters($hubUrl, $mode)
+    {
+        if (!in_array($mode, array('subscribe', 'unsubscribe'))) {
+            throw new Exception\InvalidArgumentException('Invalid mode specified: "'
+                . $mode . '" which should have been "subscribe" or "unsubscribe"');
+        }
+
+        $params = array(
+            'hub.mode'  => $mode,
+            'hub.topic' => $this->getTopicUrl(),
+        );
+
+        if ($this->getPreferredVerificationMode()
+                == PubSubHubbub::VERIFICATION_MODE_SYNC
+        ) {
+            $vmodes = array(
+                PubSubHubbub::VERIFICATION_MODE_SYNC,
+                PubSubHubbub::VERIFICATION_MODE_ASYNC,
+            );
+        } else {
+            $vmodes = array(
+                PubSubHubbub::VERIFICATION_MODE_ASYNC,
+                PubSubHubbub::VERIFICATION_MODE_SYNC,
+            );
+        }
+        $params['hub.verify'] = array();
+        foreach ($vmodes as $vmode) {
+            $params['hub.verify'][] = $vmode;
+        }
+
+        /**
+         * Establish a persistent verify_token and attach key to callback
+         * URL's path/query_string
+         */
+        $key   = $this->_generateSubscriptionKey($params, $hubUrl);
+        $token = $this->_generateVerifyToken();
+        $params['hub.verify_token'] = $token;
+
+        // Note: query string only usable with PuSH 0.2 Hubs
+        if (!$this->usePathParameter) {
+            $params['hub.callback'] = $this->getCallbackUrl()
+                . '?xhub.subscription=' . PubSubHubbub::urlencode($key);
+        } else {
+            $params['hub.callback'] = rtrim($this->getCallbackUrl(), '/')
+                . '/' . PubSubHubbub::urlencode($key);
+        }
+        if ($mode == 'subscribe' && $this->getLeaseSeconds() !== null) {
+            $params['hub.lease_seconds'] = $this->getLeaseSeconds();
+        }
+
+        // hub.secret not currently supported
+        $optParams = $this->getParameters();
+        foreach ($optParams as $name => $value) {
+            $params[$name] = $value;
+        }
+
+        // store subscription to storage
+        $now = new DateTime();
+        $expires = null;
+        if (isset($params['hub.lease_seconds'])) {
+            $expires = $now->add(new DateInterval('PT' . $params['hub.lease_seconds'] . 'S'))
+                ->format('Y-m-d H:i:s');
+        }
+        $data = array(
+            'id'                 => $key,
+            'topic_url'          => $params['hub.topic'],
+            'hub_url'            => $hubUrl,
+            'created_time'       => $now->format('Y-m-d H:i:s'),
+            'lease_seconds'      => $params['hub.lease_seconds'],
+            'verify_token'       => hash('sha256', $params['hub.verify_token']),
+            'secret'             => null,
+            'expiration_time'    => $expires,
+            'subscription_state' => ($mode == 'unsubscribe')? PubSubHubbub::SUBSCRIPTION_TODELETE : PubSubHubbub::SUBSCRIPTION_NOTVERIFIED,
+        );
+        $this->getStorage()->setSubscription($data);
+
+        return $this->_toByteValueOrderedString(
+            $this->_urlEncode($params)
+        );
+    }
+
+    /**
+     * Simple helper to generate a verification token used in (un)subscribe
+     * requests to a Hub Server. Follows no particular method, which means
+     * it might be improved/changed in future.
+     *
+     * @return string
+     */
+    protected function _generateVerifyToken()
+    {
+        if (!empty($this->testStaticToken)) {
+            return $this->testStaticToken;
+        }
+        return uniqid(rand(), true) . time();
+    }
+
+    /**
+     * Simple helper to generate a verification token used in (un)subscribe
+     * requests to a Hub Server.
+     *
+     * @param array   $params
+     * @param string $hubUrl The Hub Server URL for which this token will apply
+     * @return string
+     */
+    protected function _generateSubscriptionKey(array $params, $hubUrl)
+    {
+        $keyBase = $params['hub.topic'] . $hubUrl;
+        $key     = md5($keyBase);
+
+        return $key;
+    }
+
+    /**
+     * URL Encode an array of parameters
+     *
+     * @param  array $params
+     * @return array
+     */
+    protected function _urlEncode(array $params)
+    {
+        $encoded = array();
+        foreach ($params as $key => $value) {
+            if (is_array($value)) {
+                $ekey = PubSubHubbub::urlencode($key);
+                $encoded[$ekey] = array();
+                foreach ($value as $duplicateKey) {
+                    $encoded[$ekey][]
+                        = PubSubHubbub::urlencode($duplicateKey);
+                }
+            } else {
+                $encoded[PubSubHubbub::urlencode($key)]
+                    = PubSubHubbub::urlencode($value);
+            }
+        }
+        return $encoded;
+    }
+
+    /**
+     * Order outgoing parameters
+     *
+     * @param  array $params
+     * @return array
+     */
+    protected function _toByteValueOrderedString(array $params)
+    {
+        $return = array();
+        uksort($params, 'strnatcmp');
+        foreach ($params as $key => $value) {
+            if (is_array($value)) {
+                foreach ($value as $keyduplicate) {
+                    $return[] = $key . '=' . $keyduplicate;
+                }
+            } else {
+                $return[] = $key . '=' . $value;
+            }
+        }
+        return implode('&', $return);
+    }
+
+    /**
+     * This is STRICTLY for testing purposes only...
+     */
+    protected $testStaticToken = null;
+
+    final public function setTestStaticToken($token)
+    {
+        $this->testStaticToken = (string) $token;
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Subscriber/Callback.php b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Subscriber/Callback.php
new file mode 100644
index 000000000000..4e15e58dbaed
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Subscriber/Callback.php
@@ -0,0 +1,316 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\PubSubHubbub\Subscriber;
+
+use Zend\Feed\PubSubHubbub;
+use Zend\Feed\PubSubHubbub\Exception;
+use Zend\Feed\Uri;
+
+class Callback extends PubSubHubbub\AbstractCallback
+{
+    /**
+     * Contains the content of any feeds sent as updates to the Callback URL
+     *
+     * @var string
+     */
+    protected $feedUpdate = null;
+
+    /**
+     * Holds a manually set subscription key (i.e. identifies a unique
+     * subscription) which is typical when it is not passed in the query string
+     * but is part of the Callback URL path, requiring manual retrieval e.g.
+     * using a route and the \Zend\Mvc\Router\RouteMatch::getParam() method.
+     *
+     * @var string
+     */
+    protected $subscriptionKey = null;
+
+    /**
+     * After verification, this is set to the verified subscription's data.
+     *
+     * @var array
+     */
+    protected $currentSubscriptionData = null;
+
+    /**
+     * Set a subscription key to use for the current callback request manually.
+     * Required if usePathParameter is enabled for the Subscriber.
+     *
+     * @param  string $key
+     * @return \Zend\Feed\PubSubHubbub\Subscriber\Callback
+     */
+    public function setSubscriptionKey($key)
+    {
+        $this->subscriptionKey = $key;
+        return $this;
+    }
+
+    /**
+     * Handle any callback from a Hub Server responding to a subscription or
+     * unsubscription request. This should be the Hub Server confirming the
+     * the request prior to taking action on it.
+     *
+     * @param  array $httpGetData GET data if available and not in $_GET
+     * @param  bool $sendResponseNow Whether to send response now or when asked
+     * @return void
+     */
+    public function handle(array $httpGetData = null, $sendResponseNow = false)
+    {
+        if ($httpGetData === null) {
+            $httpGetData = $_GET;
+        }
+
+        /**
+         * Handle any feed updates (sorry for the mess :P)
+         *
+         * This DOES NOT attempt to process a feed update. Feed updates
+         * SHOULD be validated/processed by an asynchronous process so as
+         * to avoid holding up responses to the Hub.
+         */
+        $contentType = $this->_getHeader('Content-Type');
+        if (strtolower($_SERVER['REQUEST_METHOD']) == 'post'
+            && $this->_hasValidVerifyToken(null, false)
+            && (stripos($contentType, 'application/atom+xml') === 0
+                || stripos($contentType, 'application/rss+xml') === 0
+                || stripos($contentType, 'application/xml') === 0
+                || stripos($contentType, 'text/xml') === 0
+                || stripos($contentType, 'application/rdf+xml') === 0)
+        ) {
+            $this->setFeedUpdate($this->_getRawBody());
+            $this->getHttpResponse()->setHeader('X-Hub-On-Behalf-Of', $this->getSubscriberCount());
+        /**
+         * Handle any (un)subscribe confirmation requests
+         */
+        } elseif ($this->isValidHubVerification($httpGetData)) {
+            $this->getHttpResponse()->setContent($httpGetData['hub_challenge']);
+
+            switch (strtolower($httpGetData['hub_mode'])) {
+                case 'subscribe':
+                    $data = $this->currentSubscriptionData;
+                    $data['subscription_state'] = PubSubHubbub\PubSubHubbub::SUBSCRIPTION_VERIFIED;
+                    if (isset($httpGetData['hub_lease_seconds'])) {
+                        $data['lease_seconds'] = $httpGetData['hub_lease_seconds'];
+                    }
+                    $this->getStorage()->setSubscription($data);
+                    break;
+                case 'unsubscribe':
+                    $verifyTokenKey = $this->_detectVerifyTokenKey($httpGetData);
+                    $this->getStorage()->deleteSubscription($verifyTokenKey);
+                    break;
+                default:
+                    throw new Exception\RuntimeException(sprintf(
+                        'Invalid hub_mode ("%s") provided',
+                        $httpGetData['hub_mode']
+                    ));
+            }
+        /**
+         * Hey, C'mon! We tried everything else!
+         */
+        } else {
+            $this->getHttpResponse()->setStatusCode(404);
+        }
+
+        if ($sendResponseNow) {
+            $this->sendResponse();
+        }
+    }
+
+    /**
+     * Checks validity of the request simply by making a quick pass and
+     * confirming the presence of all REQUIRED parameters.
+     *
+     * @param  array $httpGetData
+     * @return bool
+     */
+    public function isValidHubVerification(array $httpGetData)
+    {
+        /**
+         * As per the specification, the hub.verify_token is OPTIONAL. This
+         * implementation of Pubsubhubbub considers it REQUIRED and will
+         * always send a hub.verify_token parameter to be echoed back
+         * by the Hub Server. Therefore, its absence is considered invalid.
+         */
+        if (strtolower($_SERVER['REQUEST_METHOD']) !== 'get') {
+            return false;
+        }
+        $required = array(
+            'hub_mode',
+            'hub_topic',
+            'hub_challenge',
+            'hub_verify_token',
+        );
+        foreach ($required as $key) {
+            if (!array_key_exists($key, $httpGetData)) {
+                return false;
+            }
+        }
+        if ($httpGetData['hub_mode'] !== 'subscribe'
+            && $httpGetData['hub_mode'] !== 'unsubscribe'
+        ) {
+            return false;
+        }
+        if ($httpGetData['hub_mode'] == 'subscribe'
+            && !array_key_exists('hub_lease_seconds', $httpGetData)
+        ) {
+            return false;
+        }
+        if (!Uri::factory($httpGetData['hub_topic'])->isValid()) {
+            return false;
+        }
+
+        /**
+         * Attempt to retrieve any Verification Token Key attached to Callback
+         * URL's path by our Subscriber implementation
+         */
+        if (!$this->_hasValidVerifyToken($httpGetData)) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Sets a newly received feed (Atom/RSS) sent by a Hub as an update to a
+     * Topic we've subscribed to.
+     *
+     * @param  string $feed
+     * @return \Zend\Feed\PubSubHubbub\Subscriber\Callback
+     */
+    public function setFeedUpdate($feed)
+    {
+        $this->feedUpdate = $feed;
+        return $this;
+    }
+
+    /**
+     * Check if any newly received feed (Atom/RSS) update was received
+     *
+     * @return bool
+     */
+    public function hasFeedUpdate()
+    {
+        if ($this->feedUpdate === null) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Gets a newly received feed (Atom/RSS) sent by a Hub as an update to a
+     * Topic we've subscribed to.
+     *
+     * @return string
+     */
+    public function getFeedUpdate()
+    {
+        return $this->feedUpdate;
+    }
+
+    /**
+     * Check for a valid verify_token. By default attempts to compare values
+     * with that sent from Hub, otherwise merely ascertains its existence.
+     *
+     * @param  array $httpGetData
+     * @param  bool $checkValue
+     * @return bool
+     */
+    protected function _hasValidVerifyToken(array $httpGetData = null, $checkValue = true)
+    {
+        $verifyTokenKey = $this->_detectVerifyTokenKey($httpGetData);
+        if (empty($verifyTokenKey)) {
+            return false;
+        }
+        $verifyTokenExists = $this->getStorage()->hasSubscription($verifyTokenKey);
+        if (!$verifyTokenExists) {
+            return false;
+        }
+        if ($checkValue) {
+            $data = $this->getStorage()->getSubscription($verifyTokenKey);
+            $verifyToken = $data['verify_token'];
+            if ($verifyToken !== hash('sha256', $httpGetData['hub_verify_token'])) {
+                return false;
+            }
+            $this->currentSubscriptionData = $data;
+            return true;
+        }
+        return true;
+    }
+
+    /**
+     * Attempt to detect the verification token key. This would be passed in
+     * the Callback URL (which we are handling with this class!) as a URI
+     * path part (the last part by convention).
+     *
+     * @param  null|array $httpGetData
+     * @return false|string
+     */
+    protected function _detectVerifyTokenKey(array $httpGetData = null)
+    {
+        /**
+         * Available when sub keys encoding in Callback URL path
+         */
+        if (isset($this->subscriptionKey)) {
+            return $this->subscriptionKey;
+        }
+
+        /**
+         * Available only if allowed by PuSH 0.2 Hubs
+         */
+        if (is_array($httpGetData)
+            && isset($httpGetData['xhub_subscription'])
+        ) {
+            return $httpGetData['xhub_subscription'];
+        }
+
+        /**
+         * Available (possibly) if corrupted in transit and not part of $_GET
+         */
+        $params = $this->_parseQueryString();
+        if (isset($params['xhub.subscription'])) {
+            return rawurldecode($params['xhub.subscription']);
+        }
+
+        return false;
+    }
+
+    /**
+     * Build an array of Query String parameters.
+     * This bypasses $_GET which munges parameter names and cannot accept
+     * multiple parameters with the same key.
+     *
+     * @return array|void
+     */
+    protected function _parseQueryString()
+    {
+        $params      = array();
+        $queryString = '';
+        if (isset($_SERVER['QUERY_STRING'])) {
+            $queryString = $_SERVER['QUERY_STRING'];
+        }
+        if (empty($queryString)) {
+            return array();
+        }
+        $parts = explode('&', $queryString);
+        foreach ($parts as $kvpair) {
+            $pair  = explode('=', $kvpair);
+            $key   = rawurldecode($pair[0]);
+            $value = rawurldecode($pair[1]);
+            if (isset($params[$key])) {
+                if (is_array($params[$key])) {
+                    $params[$key][] = $value;
+                } else {
+                    $params[$key] = array($params[$key], $value);
+                }
+            } else {
+                $params[$key] = $value;
+            }
+        }
+        return $params;
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Version.php b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Version.php
new file mode 100644
index 000000000000..026fe3b9a256
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/PubSubHubbub/Version.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\PubSubHubbub;
+
+abstract class Version
+{
+    const VERSION = '2';
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/README.md b/core/vendor/zendframework/zend-feed/Zend/Feed/README.md
new file mode 100644
index 000000000000..ffc73a9c262e
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/README.md
@@ -0,0 +1,15 @@
+Feed Component from ZF2
+=======================
+
+This is the Feed component for ZF2.
+
+- File issues at https://github.com/zendframework/zf2/issues
+- Create pull requests against https://github.com/zendframework/zf2
+- Documentation is at http://framework.zend.com/docs
+
+LICENSE
+-------
+
+The files in this archive are released under the [Zend Framework
+license](http://framework.zend.com/license), which is a 3-clause BSD license.
+
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/AbstractEntry.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/AbstractEntry.php
new file mode 100644
index 000000000000..797562eaa03a
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/AbstractEntry.php
@@ -0,0 +1,224 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader;
+
+use DOMDocument;
+use DOMElement;
+use DOMXPath;
+
+abstract class AbstractEntry
+{
+    /**
+     * Feed entry data
+     *
+     * @var array
+     */
+    protected $data = array();
+
+    /**
+     * DOM document object
+     *
+     * @var DOMDocument
+     */
+    protected $domDocument = null;
+
+    /**
+     * Entry instance
+     *
+     * @var DOMElement
+     */
+    protected $entry = null;
+
+    /**
+     * Pointer to the current entry
+     *
+     * @var int
+     */
+    protected $entryKey = 0;
+
+    /**
+     * XPath object
+     *
+     * @var DOMXPath
+     */
+    protected $xpath = null;
+
+    /**
+     * Registered extensions
+     *
+     * @var array
+     */
+    protected $extensions = array();
+
+    /**
+     * Constructor
+     *
+     * @param  DOMElement $entry
+     * @param  int $entryKey
+     * @param  null|string $type
+     */
+    public function __construct(DOMElement $entry, $entryKey, $type = null)
+    {
+        $this->entry       = $entry;
+        $this->entryKey    = $entryKey;
+        $this->domDocument = $entry->ownerDocument;
+        if ($type !== null) {
+            $this->data['type'] = $type;
+        } else {
+            $this->data['type'] = Reader::detectType($entry);
+        }
+        $this->_loadExtensions();
+    }
+
+    /**
+     * Get the DOM
+     *
+     * @return DOMDocument
+     */
+    public function getDomDocument()
+    {
+        return $this->domDocument;
+    }
+
+    /**
+     * Get the entry element
+     *
+     * @return DOMElement
+     */
+    public function getElement()
+    {
+        return $this->entry;
+    }
+
+    /**
+     * Get the Entry's encoding
+     *
+     * @return string
+     */
+    public function getEncoding()
+    {
+        $assumed = $this->getDomDocument()->encoding;
+        if (empty($assumed)) {
+            $assumed = 'UTF-8';
+        }
+        return $assumed;
+    }
+
+    /**
+     * Get entry as xml
+     *
+     * @return string
+     */
+    public function saveXml()
+    {
+        $dom = new DOMDocument('1.0', $this->getEncoding());
+        $entry = $dom->importNode($this->getElement(), true);
+        $dom->appendChild($entry);
+        return $dom->saveXml();
+    }
+
+    /**
+     * Get the entry type
+     *
+     * @return string
+     */
+    public function getType()
+    {
+        return $this->data['type'];
+    }
+
+    /**
+     * Get the XPath query object
+     *
+     * @return DOMXPath
+     */
+    public function getXpath()
+    {
+        if (!$this->xpath) {
+            $this->setXpath(new DOMXPath($this->getDomDocument()));
+        }
+        return $this->xpath;
+    }
+
+    /**
+     * Set the XPath query
+     *
+     * @param  DOMXPath $xpath
+     * @return \Zend\Feed\Reader\AbstractEntry
+     */
+    public function setXpath(DOMXPath $xpath)
+    {
+        $this->xpath = $xpath;
+        return $this;
+    }
+
+    /**
+     * Get registered extensions
+     *
+     * @return array
+     */
+    public function getExtensions()
+    {
+        return $this->extensions;
+    }
+
+    /**
+     * Return an Extension object with the matching name (postfixed with _Entry)
+     *
+     * @param string $name
+     * @return \Zend\Feed\Reader\Extension\AbstractEntry
+     */
+    public function getExtension($name)
+    {
+        if (array_key_exists($name . '\Entry', $this->extensions)) {
+            return $this->extensions[$name . '\Entry'];
+        }
+        return null;
+    }
+
+    /**
+     * Method overloading: call given method on first extension implementing it
+     *
+     * @param  string $method
+     * @param  array $args
+     * @return mixed
+     * @throws Exception\BadMethodCallException if no extensions implements the method
+     */
+    public function __call($method, $args)
+    {
+        foreach ($this->extensions as $extension) {
+            if (method_exists($extension, $method)) {
+                return call_user_func_array(array($extension, $method), $args);
+            }
+        }
+        throw new Exception\BadMethodCallException('Method: ' . $method
+            . 'does not exist and could not be located on a registered Extension');
+    }
+
+    /**
+     * Load extensions from Zend\Feed\Reader\Reader
+     *
+     * @return void
+     */
+    protected function _loadExtensions()
+    {
+        $all = Reader::getExtensions();
+        $feed = $all['entry'];
+        foreach ($feed as $extension) {
+            if (in_array($extension, $all['core'])) {
+                continue;
+            }
+            $className = Reader::getPluginLoader()->getClassName($extension);
+            $this->extensions[$extension] = new $className(
+                $this->getElement(), $this->entryKey, $this->data['type']
+            );
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/AbstractFeed.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/AbstractFeed.php
new file mode 100644
index 000000000000..6a5cee33a56d
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/AbstractFeed.php
@@ -0,0 +1,300 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader;
+
+use DOMDocument;
+use DOMElement;
+use DOMXPath;
+
+abstract class AbstractFeed implements Feed\FeedInterface
+{
+    /**
+     * Parsed feed data
+     *
+     * @var array
+     */
+    protected $data = array();
+
+    /**
+     * Parsed feed data in the shape of a DOMDocument
+     *
+     * @var DOMDocument
+     */
+    protected $domDocument = null;
+
+    /**
+     * An array of parsed feed entries
+     *
+     * @var array
+     */
+    protected $entries = array();
+
+    /**
+     * A pointer for the iterator to keep track of the entries array
+     *
+     * @var int
+     */
+    protected $entriesKey = 0;
+
+    /**
+     * The base XPath query used to retrieve feed data
+     *
+     * @var DOMXPath
+     */
+    protected $xpath = null;
+
+    /**
+     * Array of loaded extensions
+     *
+     * @var array
+     */
+    protected $extensions = array();
+
+    /**
+     * Original Source URI (set if imported from a URI)
+     *
+     * @var string
+     */
+    protected $originalSourceUri = null;
+
+    /**
+     * Constructor
+     *
+     * @param DomDocument $domDocument The DOM object for the feed's XML
+     * @param string $type Feed type
+     */
+    public function __construct(DOMDocument $domDocument, $type = null)
+    {
+        $this->domDocument = $domDocument;
+        $this->xpath = new DOMXPath($this->domDocument);
+
+        if ($type !== null) {
+            $this->data['type'] = $type;
+        } else {
+            $this->data['type'] = Reader::detectType($this->domDocument);
+        }
+        $this->registerNamespaces();
+        $this->indexEntries();
+        $this->loadExtensions();
+    }
+
+    /**
+     * Set an original source URI for the feed being parsed. This value
+     * is returned from getFeedLink() method if the feed does not carry
+     * a self-referencing URI.
+     *
+     * @param string $uri
+     */
+    public function setOriginalSourceUri($uri)
+    {
+        $this->originalSourceUri = $uri;
+    }
+
+    /**
+     * Get an original source URI for the feed being parsed. Returns null if
+     * unset or the feed was not imported from a URI.
+     *
+     * @return string|null
+     */
+    public function getOriginalSourceUri()
+    {
+        return $this->originalSourceUri;
+    }
+
+    /**
+     * Get the number of feed entries.
+     * Required by the Iterator interface.
+     *
+     * @return int
+     */
+    public function count()
+    {
+        return count($this->entries);
+    }
+
+    /**
+     * Return the current entry
+     *
+     * @return \Zend\Feed\Reader\AbstractEntry
+     */
+    public function current()
+    {
+        if (substr($this->getType(), 0, 3) == 'rss') {
+            $reader = new Entry\RSS($this->entries[$this->key()], $this->key(), $this->getType());
+        } else {
+            $reader = new Entry\Atom($this->entries[$this->key()], $this->key(), $this->getType());
+        }
+
+        $reader->setXpath($this->xpath);
+
+        return $reader;
+    }
+
+    /**
+     * Get the DOM
+     *
+     * @return DOMDocument
+     */
+    public function getDomDocument()
+    {
+        return $this->domDocument;
+    }
+
+    /**
+     * Get the Feed's encoding
+     *
+     * @return string
+     */
+    public function getEncoding()
+    {
+        $assumed = $this->getDomDocument()->encoding;
+        if (empty($assumed)) {
+            $assumed = 'UTF-8';
+        }
+        return $assumed;
+    }
+
+    /**
+     * Get feed as xml
+     *
+     * @return string
+     */
+    public function saveXml()
+    {
+          return $this->getDomDocument()->saveXml();
+    }
+
+    /**
+     * Get the DOMElement representing the items/feed element
+     *
+     * @return DOMElement
+     */
+    public function getElement()
+    {
+          return $this->getDomDocument()->documentElement;
+    }
+
+    /**
+     * Get the DOMXPath object for this feed
+     *
+     * @return DOMXPath
+     */
+    public function getXpath()
+    {
+          return $this->xpath;
+    }
+
+    /**
+     * Get the feed type
+     *
+     * @return string
+     */
+    public function getType()
+    {
+        return $this->data['type'];
+    }
+
+    /**
+     * Return the current feed key
+     *
+     * @return int
+     */
+    public function key()
+    {
+        return $this->entriesKey;
+    }
+
+    /**
+     * Move the feed pointer forward
+     *
+     */
+    public function next()
+    {
+        ++$this->entriesKey;
+    }
+
+    /**
+     * Reset the pointer in the feed object
+     *
+     */
+    public function rewind()
+    {
+        $this->entriesKey = 0;
+    }
+
+    /**
+     * Check to see if the iterator is still valid
+     *
+     * @return bool
+     */
+    public function valid()
+    {
+        return 0 <= $this->entriesKey && $this->entriesKey < $this->count();
+    }
+
+    public function getExtensions()
+    {
+        return $this->extensions;
+    }
+
+    public function __call($method, $args)
+    {
+        foreach ($this->extensions as $extension) {
+            if (method_exists($extension, $method)) {
+                return call_user_func_array(array($extension, $method), $args);
+            }
+        }
+        throw new Exception\BadMethodCallException('Method: ' . $method
+        . 'does not exist and could not be located on a registered Extension');
+    }
+
+    /**
+     * Return an Extension object with the matching name (postfixed with _Feed)
+     *
+     * @param string $name
+     * @return \Zend\Feed\Reader\Extension\AbstractFeed
+     */
+    public function getExtension($name)
+    {
+        if (array_key_exists($name . '\Feed', $this->extensions)) {
+            return $this->extensions[$name . '\Feed'];
+        }
+        return null;
+    }
+
+    protected function loadExtensions()
+    {
+        $all     = Reader::getExtensions();
+        $manager = Reader::getExtensionManager();
+        $feed    = $all['feed'];
+        foreach ($feed as $extension) {
+            if (in_array($extension, $all['core'])) {
+                continue;
+            }
+            $plugin = $manager->get($extension);
+            $plugin->setDomDocument($this->getDomDocument());
+            $plugin->setType($this->data['type']);
+            $plugin->setXpath($this->xpath);
+            $this->extensions[$extension] = $plugin;
+        }
+    }
+
+    /**
+     * Read all entries to the internal entries array
+     *
+     */
+    abstract protected function indexEntries();
+
+    /**
+     * Register the default namespaces for the current feed format
+     *
+     */
+    abstract protected function registerNamespaces();
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Collection.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Collection.php
new file mode 100644
index 000000000000..32144dfa23c5
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Collection.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader;
+
+class Collection extends \ArrayObject
+{
+
+
+
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Collection/AbstractCollection.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Collection/AbstractCollection.php
new file mode 100644
index 000000000000..8c64ec99cc21
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Collection/AbstractCollection.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Collection;
+
+abstract class AbstractCollection extends \ArrayObject
+{
+
+    /**
+     * Return a simple array of the most relevant slice of
+     * the collection values. For example, feed categories contain
+     * the category name, domain/URI, and other data. This method would
+     * merely return the most useful data - i.e. the category names.
+     *
+     * @return array
+     */
+    abstract public function getValues();
+
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Collection/Author.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Collection/Author.php
new file mode 100644
index 000000000000..15aa32834be8
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Collection/Author.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Collection;
+
+class Author extends AbstractCollection
+{
+
+    /**
+     * Return a simple array of the most relevant slice of
+     * the author values, i.e. all author names.
+     *
+     * @return array
+     */
+    public function getValues()
+    {
+        $authors = array();
+        foreach ($this->getIterator() as $element) {
+            $authors[] = $element['name'];
+        }
+        return array_unique($authors);
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Collection/Category.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Collection/Category.php
new file mode 100644
index 000000000000..2739bc833941
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Collection/Category.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Collection;
+
+class Category extends AbstractCollection
+{
+
+    /**
+     * Return a simple array of the most relevant slice of
+     * the collection values. For example, feed categories contain
+     * the category name, domain/URI, and other data. This method would
+     * merely return the most useful data - i.e. the category names.
+     *
+     * @return array
+     */
+    public function getValues()
+    {
+        $categories = array();
+        foreach ($this->getIterator() as $element) {
+            if (isset($element['label']) && !empty($element['label'])) {
+                $categories[] = $element['label'];
+            } else {
+                $categories[] = $element['term'];
+            }
+        }
+        return array_unique($categories);
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Collection/Collection.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Collection/Collection.php
new file mode 100644
index 000000000000..820a695ab926
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Collection/Collection.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Collection;
+
+class Collection extends \ArrayObject
+{
+
+
+
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Entry/AbstractEntry.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Entry/AbstractEntry.php
new file mode 100644
index 000000000000..68ff4f948592
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Entry/AbstractEntry.php
@@ -0,0 +1,230 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Entry;
+
+use DOMDocument;
+use DOMElement;
+use DOMXPath;
+use Zend\Feed\Reader;
+use Zend\Feed\Reader\Exception;
+
+abstract class AbstractEntry
+{
+    /**
+     * Feed entry data
+     *
+     * @var array
+     */
+    protected $data = array();
+
+    /**
+     * DOM document object
+     *
+     * @var DOMDocument
+     */
+    protected $domDocument = null;
+
+    /**
+     * Entry instance
+     *
+     * @var DOMElement
+     */
+    protected $entry = null;
+
+    /**
+     * Pointer to the current entry
+     *
+     * @var int
+     */
+    protected $entryKey = 0;
+
+    /**
+     * XPath object
+     *
+     * @var DOMXPath
+     */
+    protected $xpath = null;
+
+    /**
+     * Registered extensions
+     *
+     * @var array
+     */
+    protected $extensions = array();
+
+    /**
+     * Constructor
+     *
+     * @param  DOMElement $entry
+     * @param  int $entryKey
+     * @param  string $type
+     */
+    public function __construct(DOMElement $entry, $entryKey, $type = null)
+    {
+        $this->entry       = $entry;
+        $this->entryKey    = $entryKey;
+        $this->domDocument = $entry->ownerDocument;
+        if ($type !== null) {
+            $this->data['type'] = $type;
+        } elseif ($this->domDocument !== null) {
+            $this->data['type'] = Reader\Reader::detectType($this->domDocument);
+        } else {
+            $this->data['type'] = Reader\Reader::TYPE_ANY;
+        }
+        $this->loadExtensions();
+    }
+
+    /**
+     * Get the DOM
+     *
+     * @return DOMDocument
+     */
+    public function getDomDocument()
+    {
+        return $this->domDocument;
+    }
+
+    /**
+     * Get the entry element
+     *
+     * @return DOMElement
+     */
+    public function getElement()
+    {
+        return $this->entry;
+    }
+
+    /**
+     * Get the Entry's encoding
+     *
+     * @return string
+     */
+    public function getEncoding()
+    {
+        $assumed = $this->getDomDocument()->encoding;
+        if (empty($assumed)) {
+            $assumed = 'UTF-8';
+        }
+        return $assumed;
+    }
+
+    /**
+     * Get entry as xml
+     *
+     * @return string
+     */
+    public function saveXml()
+    {
+        $dom = new DOMDocument('1.0', $this->getEncoding());
+        $entry = $dom->importNode($this->getElement(), true);
+        $dom->appendChild($entry);
+        return $dom->saveXml();
+    }
+
+    /**
+     * Get the entry type
+     *
+     * @return string
+     */
+    public function getType()
+    {
+        return $this->data['type'];
+    }
+
+    /**
+     * Get the XPath query object
+     *
+     * @return DOMXPath
+     */
+    public function getXpath()
+    {
+        if (!$this->xpath) {
+            $this->setXpath(new DOMXPath($this->getDomDocument()));
+        }
+        return $this->xpath;
+    }
+
+    /**
+     * Set the XPath query
+     *
+     * @param  DOMXPath $xpath
+     * @return AbstractEntry
+     */
+    public function setXpath(DOMXPath $xpath)
+    {
+        $this->xpath = $xpath;
+        return $this;
+    }
+
+    /**
+     * Get registered extensions
+     *
+     * @return array
+     */
+    public function getExtensions()
+    {
+        return $this->extensions;
+    }
+
+    /**
+     * Return an Extension object with the matching name (postfixed with _Entry)
+     *
+     * @param string $name
+     * @return Reader\Extension\AbstractEntry
+     */
+    public function getExtension($name)
+    {
+        if (array_key_exists($name . '\\Entry', $this->extensions)) {
+            return $this->extensions[$name . '\\Entry'];
+        }
+        return null;
+    }
+
+    /**
+     * Method overloading: call given method on first extension implementing it
+     *
+     * @param  string $method
+     * @param  array $args
+     * @return mixed
+     * @throws Exception\RuntimeException if no extensions implements the method
+     */
+    public function __call($method, $args)
+    {
+        foreach ($this->extensions as $extension) {
+            if (method_exists($extension, $method)) {
+                return call_user_func_array(array($extension, $method), $args);
+            }
+        }
+        throw new Exception\RuntimeException('Method: ' . $method
+            . ' does not exist and could not be located on a registered Extension');
+    }
+
+    /**
+     * Load extensions from Zend\Feed\Reader\Reader
+     *
+     * @return void
+     */
+    protected function loadExtensions()
+    {
+        $all     = Reader\Reader::getExtensions();
+        $manager = Reader\Reader::getExtensionManager();
+        $feed    = $all['entry'];
+        foreach ($feed as $extension) {
+            if (in_array($extension, $all['core'])) {
+                continue;
+            }
+            $plugin = $manager->get($extension);
+            $plugin->setEntryElement($this->getElement());
+            $plugin->setEntryKey($this->entryKey);
+            $plugin->setType($this->data['type']);
+            $this->extensions[$extension] = $plugin;
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Entry/Atom.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Entry/Atom.php
new file mode 100644
index 000000000000..fcd5f60f90f8
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Entry/Atom.php
@@ -0,0 +1,370 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Entry;
+
+use DOMElement;
+use DOMXPath;
+use Zend\Feed\Reader;
+
+class Atom extends AbstractEntry implements EntryInterface
+{
+    /**
+     * XPath query
+     *
+     * @var string
+     */
+    protected $xpathQuery = '';
+
+    /**
+     * Constructor
+     *
+     * @param  DOMElement $entry
+     * @param  int $entryKey
+     * @param  string $type
+     */
+    public function __construct(DOMElement $entry, $entryKey, $type = null)
+    {
+        parent::__construct($entry, $entryKey, $type);
+
+        // Everyone by now should know XPath indices start from 1 not 0
+        $this->xpathQuery = '//atom:entry[' . ($this->entryKey + 1) . ']';
+
+        $manager    = Reader\Reader::getExtensionManager();
+        $extensions = array('Atom\Entry', 'Thread\Entry', 'DublinCore\Entry');
+
+        foreach ($extensions as $name) {
+            $extension = $manager->get($name);
+            $extension->setEntryElement($entry);
+            $extension->setEntryKey($entryKey);
+            $extension->setType($type);
+            $this->extensions[$name] = $extension;
+        }
+    }
+
+    /**
+     * Get the specified author
+     *
+     * @param  int $index
+     * @return string|null
+     */
+    public function getAuthor($index = 0)
+    {
+        $authors = $this->getAuthors();
+
+        if (isset($authors[$index])) {
+            return $authors[$index];
+        }
+
+        return null;
+    }
+
+    /**
+     * Get an array with feed authors
+     *
+     * @return array
+     */
+    public function getAuthors()
+    {
+        if (array_key_exists('authors', $this->data)) {
+            return $this->data['authors'];
+        }
+
+        $people = $this->getExtension('Atom')->getAuthors();
+
+        $this->data['authors'] = $people;
+
+        return $this->data['authors'];
+    }
+
+    /**
+     * Get the entry content
+     *
+     * @return string
+     */
+    public function getContent()
+    {
+        if (array_key_exists('content', $this->data)) {
+            return $this->data['content'];
+        }
+
+        $content = $this->getExtension('Atom')->getContent();
+
+        $this->data['content'] = $content;
+
+        return $this->data['content'];
+    }
+
+    /**
+     * Get the entry creation date
+     *
+     * @return string
+     */
+    public function getDateCreated()
+    {
+        if (array_key_exists('datecreated', $this->data)) {
+            return $this->data['datecreated'];
+        }
+
+        $dateCreated = $this->getExtension('Atom')->getDateCreated();
+
+        $this->data['datecreated'] = $dateCreated;
+
+        return $this->data['datecreated'];
+    }
+
+    /**
+     * Get the entry modification date
+     *
+     * @return string
+     */
+    public function getDateModified()
+    {
+        if (array_key_exists('datemodified', $this->data)) {
+            return $this->data['datemodified'];
+        }
+
+        $dateModified = $this->getExtension('Atom')->getDateModified();
+
+        $this->data['datemodified'] = $dateModified;
+
+        return $this->data['datemodified'];
+    }
+
+    /**
+     * Get the entry description
+     *
+     * @return string
+     */
+    public function getDescription()
+    {
+        if (array_key_exists('description', $this->data)) {
+            return $this->data['description'];
+        }
+
+        $description = $this->getExtension('Atom')->getDescription();
+
+        $this->data['description'] = $description;
+
+        return $this->data['description'];
+    }
+
+    /**
+     * Get the entry enclosure
+     *
+     * @return string
+     */
+    public function getEnclosure()
+    {
+        if (array_key_exists('enclosure', $this->data)) {
+            return $this->data['enclosure'];
+        }
+
+        $enclosure = $this->getExtension('Atom')->getEnclosure();
+
+        $this->data['enclosure'] = $enclosure;
+
+        return $this->data['enclosure'];
+    }
+
+    /**
+     * Get the entry ID
+     *
+     * @return string
+     */
+    public function getId()
+    {
+        if (array_key_exists('id', $this->data)) {
+            return $this->data['id'];
+        }
+
+        $id = $this->getExtension('Atom')->getId();
+
+        $this->data['id'] = $id;
+
+        return $this->data['id'];
+    }
+
+    /**
+     * Get a specific link
+     *
+     * @param  int $index
+     * @return string
+     */
+    public function getLink($index = 0)
+    {
+        if (!array_key_exists('links', $this->data)) {
+            $this->getLinks();
+        }
+
+        if (isset($this->data['links'][$index])) {
+            return $this->data['links'][$index];
+        }
+
+        return null;
+    }
+
+    /**
+     * Get all links
+     *
+     * @return array
+     */
+    public function getLinks()
+    {
+        if (array_key_exists('links', $this->data)) {
+            return $this->data['links'];
+        }
+
+        $links = $this->getExtension('Atom')->getLinks();
+
+        $this->data['links'] = $links;
+
+        return $this->data['links'];
+    }
+
+    /**
+     * Get a permalink to the entry
+     *
+     * @return string
+     */
+    public function getPermalink()
+    {
+        return $this->getLink(0);
+    }
+
+    /**
+     * Get the entry title
+     *
+     * @return string
+     */
+    public function getTitle()
+    {
+        if (array_key_exists('title', $this->data)) {
+            return $this->data['title'];
+        }
+
+        $title = $this->getExtension('Atom')->getTitle();
+
+        $this->data['title'] = $title;
+
+        return $this->data['title'];
+    }
+
+    /**
+     * Get the number of comments/replies for current entry
+     *
+     * @return int
+     */
+    public function getCommentCount()
+    {
+        if (array_key_exists('commentcount', $this->data)) {
+            return $this->data['commentcount'];
+        }
+
+        $commentcount = $this->getExtension('Thread')->getCommentCount();
+
+        if (!$commentcount) {
+            $commentcount = $this->getExtension('Atom')->getCommentCount();
+        }
+
+        $this->data['commentcount'] = $commentcount;
+
+        return $this->data['commentcount'];
+    }
+
+    /**
+     * Returns a URI pointing to the HTML page where comments can be made on this entry
+     *
+     * @return string
+     */
+    public function getCommentLink()
+    {
+        if (array_key_exists('commentlink', $this->data)) {
+            return $this->data['commentlink'];
+        }
+
+        $commentlink = $this->getExtension('Atom')->getCommentLink();
+
+        $this->data['commentlink'] = $commentlink;
+
+        return $this->data['commentlink'];
+    }
+
+    /**
+     * Returns a URI pointing to a feed of all comments for this entry
+     *
+     * @return string
+     */
+    public function getCommentFeedLink()
+    {
+        if (array_key_exists('commentfeedlink', $this->data)) {
+            return $this->data['commentfeedlink'];
+        }
+
+        $commentfeedlink = $this->getExtension('Atom')->getCommentFeedLink();
+
+        $this->data['commentfeedlink'] = $commentfeedlink;
+
+        return $this->data['commentfeedlink'];
+    }
+
+    /**
+     * Get category data as a Reader\Reader_Collection_Category object
+     *
+     * @return Reader\Collection\Category
+     */
+    public function getCategories()
+    {
+        if (array_key_exists('categories', $this->data)) {
+            return $this->data['categories'];
+        }
+
+        $categoryCollection = $this->getExtension('Atom')->getCategories();
+
+        if (count($categoryCollection) == 0) {
+            $categoryCollection = $this->getExtension('DublinCore')->getCategories();
+        }
+
+        $this->data['categories'] = $categoryCollection;
+
+        return $this->data['categories'];
+    }
+
+    /**
+     * Get source feed metadata from the entry
+     *
+     * @return Reader\Feed\Atom\Source|null
+     */
+    public function getSource()
+    {
+        if (array_key_exists('source', $this->data)) {
+            return $this->data['source'];
+        }
+
+        $source = $this->getExtension('Atom')->getSource();
+
+        $this->data['source'] = $source;
+
+        return $this->data['source'];
+    }
+
+    /**
+     * Set the XPath query (incl. on all Extensions)
+     *
+     * @param DOMXPath $xpath
+     * @return void
+     */
+    public function setXpath(DOMXPath $xpath)
+    {
+        parent::setXpath($xpath);
+        foreach ($this->extensions as $extension) {
+            $extension->setXpath($this->xpath);
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Entry/EntryInterface.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Entry/EntryInterface.php
new file mode 100644
index 000000000000..29b437a2ca23
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Entry/EntryInterface.php
@@ -0,0 +1,129 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Entry;
+
+use Zend\Feed\Reader\Collection\Category;
+
+interface EntryInterface
+{
+    /**
+     * Get the specified author
+     *
+     * @param  int $index
+     * @return string|null
+     */
+    public function getAuthor($index = 0);
+
+    /**
+     * Get an array with feed authors
+     *
+     * @return array
+     */
+    public function getAuthors();
+
+    /**
+     * Get the entry content
+     *
+     * @return string
+     */
+    public function getContent();
+
+    /**
+     * Get the entry creation date
+     *
+     * @return string
+     */
+    public function getDateCreated();
+
+    /**
+     * Get the entry modification date
+     *
+     * @return string
+     */
+    public function getDateModified();
+
+    /**
+     * Get the entry description
+     *
+     * @return string
+     */
+    public function getDescription();
+
+    /**
+     * Get the entry enclosure
+     *
+     * @return \stdClass
+     */
+    public function getEnclosure();
+
+    /**
+     * Get the entry ID
+     *
+     * @return string
+     */
+    public function getId();
+
+    /**
+     * Get a specific link
+     *
+     * @param  int $index
+     * @return string
+     */
+    public function getLink($index = 0);
+
+    /**
+     * Get all links
+     *
+     * @return array
+     */
+    public function getLinks();
+
+    /**
+     * Get a permalink to the entry
+     *
+     * @return string
+     */
+    public function getPermalink();
+
+    /**
+     * Get the entry title
+     *
+     * @return string
+     */
+    public function getTitle();
+
+    /**
+     * Get the number of comments/replies for current entry
+     *
+     * @return int
+     */
+    public function getCommentCount();
+
+    /**
+     * Returns a URI pointing to the HTML page where comments can be made on this entry
+     *
+     * @return string
+     */
+    public function getCommentLink();
+
+    /**
+     * Returns a URI pointing to a feed of all comments for this entry
+     *
+     * @return string
+     */
+    public function getCommentFeedLink();
+
+    /**
+     * Get all categories
+     *
+     * @return Category
+     */
+    public function getCategories();
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Entry/Rss.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Entry/Rss.php
new file mode 100644
index 000000000000..274d0d5865bd
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Entry/Rss.php
@@ -0,0 +1,599 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Entry;
+
+use DateTime;
+use DOMElement;
+use DOMXPath;
+use Zend\Feed\Reader;
+use Zend\Feed\Reader\Exception;
+
+class Rss extends AbstractEntry implements EntryInterface
+{
+
+    /**
+     * XPath query for RDF
+     *
+     * @var string
+     */
+    protected $xpathQueryRdf = '';
+
+    /**
+     * XPath query for RSS
+     *
+     * @var string
+     */
+    protected $xpathQueryRss = '';
+
+    /**
+     * Constructor
+     *
+     * @param  DOMElement $entry
+     * @param  string $entryKey
+     * @param  string $type
+     */
+    public function __construct(DOMElement $entry, $entryKey, $type = null)
+    {
+        parent::__construct($entry, $entryKey, $type);
+        $this->xpathQueryRss = '//item[' . ($this->entryKey+1) . ']';
+        $this->xpathQueryRdf = '//rss:item[' . ($this->entryKey+1) . ']';
+
+        $manager    = Reader\Reader::getExtensionManager();
+        $extensions = array(
+            'DublinCore\Entry',
+            'Content\Entry',
+            'Atom\Entry',
+            'WellFormedWeb\Entry',
+            'Slash\Entry',
+            'Thread\Entry',
+        );
+        foreach ($extensions as $name) {
+            $extension = $manager->get($name);
+            $extension->setEntryElement($entry);
+            $extension->setEntryKey($entryKey);
+            $extension->setType($type);
+            $this->extensions[$name] = $extension;
+        }
+    }
+
+    /**
+     * Get an author entry
+     *
+     * @param int $index
+     * @return string
+     */
+    public function getAuthor($index = 0)
+    {
+        $authors = $this->getAuthors();
+
+        if (isset($authors[$index])) {
+            return $authors[$index];
+        }
+
+        return null;
+    }
+
+    /**
+     * Get an array with feed authors
+     *
+     * @return array
+     */
+    public function getAuthors()
+    {
+        if (array_key_exists('authors', $this->data)) {
+            return $this->data['authors'];
+        }
+
+        $authors = array();
+        $authorsDc = $this->getExtension('DublinCore')->getAuthors();
+        if (!empty($authorsDc)) {
+            foreach ($authorsDc as $author) {
+                $authors[] = array(
+                    'name' => $author['name']
+                );
+            }
+        }
+
+        if ($this->getType() !== Reader\Reader::TYPE_RSS_10
+        && $this->getType() !== Reader\Reader::TYPE_RSS_090) {
+            $list = $this->xpath->query($this->xpathQueryRss . '//author');
+        } else {
+            $list = $this->xpath->query($this->xpathQueryRdf . '//rss:author');
+        }
+        if ($list->length) {
+            foreach ($list as $author) {
+                $string = trim($author->nodeValue);
+                $email = null;
+                $name = null;
+                $data = array();
+                // Pretty rough parsing - but it's a catchall
+                if (preg_match("/^.*@[^ ]*/", $string, $matches)) {
+                    $data['email'] = trim($matches[0]);
+                    if (preg_match("/\((.*)\)$/", $string, $matches)) {
+                        $data['name'] = $matches[1];
+                    }
+                    $authors[] = $data;
+                }
+            }
+        }
+
+        if (count($authors) == 0) {
+            $authors = $this->getExtension('Atom')->getAuthors();
+        } else {
+            $authors = new Reader\Collection\Author(
+                Reader\Reader::arrayUnique($authors)
+            );
+        }
+
+        if (count($authors) == 0) {
+            $authors = null;
+        }
+
+        $this->data['authors'] = $authors;
+
+        return $this->data['authors'];
+    }
+
+    /**
+     * Get the entry content
+     *
+     * @return string
+     */
+    public function getContent()
+    {
+        if (array_key_exists('content', $this->data)) {
+            return $this->data['content'];
+        }
+
+        $content = $this->getExtension('Content')->getContent();
+
+        if (!$content) {
+            $content = $this->getDescription();
+        }
+
+        if (empty($content)) {
+            $content = $this->getExtension('Atom')->getContent();
+        }
+
+        $this->data['content'] = $content;
+
+        return $this->data['content'];
+    }
+
+    /**
+     * Get the entry's date of creation
+     *
+     * @return string
+     */
+    public function getDateCreated()
+    {
+        return $this->getDateModified();
+    }
+
+    /**
+     * Get the entry's date of modification
+     *
+     * @throws Exception\RuntimeException
+     * @return string
+     */
+    public function getDateModified()
+    {
+        if (array_key_exists('datemodified', $this->data)) {
+            return $this->data['datemodified'];
+        }
+
+        $dateModified = null;
+        $date = null;
+
+        if ($this->getType() !== Reader\Reader::TYPE_RSS_10
+            && $this->getType() !== Reader\Reader::TYPE_RSS_090
+        ) {
+            $dateModified = $this->xpath->evaluate('string(' . $this->xpathQueryRss . '/pubDate)');
+            if ($dateModified) {
+                $dateModifiedParsed = strtotime($dateModified);
+                if ($dateModifiedParsed) {
+                    $date = new DateTime('@' . $dateModifiedParsed);
+                } else {
+                    $dateStandards = array(DateTime::RSS, DateTime::RFC822,
+                                           DateTime::RFC2822, null);
+                    foreach ($dateStandards as $standard) {
+                        try {
+                            $date = date_create_from_format($standard, $dateModified);
+                            break;
+                        } catch (\Exception $e) {
+                            if ($standard == null) {
+                                throw new Exception\RuntimeException(
+                                    'Could not load date due to unrecognised'
+                                    .' format (should follow RFC 822 or 2822):'
+                                    . $e->getMessage(),
+                                    0, $e
+                                );
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        if (!$date) {
+            $date = $this->getExtension('DublinCore')->getDate();
+        }
+
+        if (!$date) {
+            $date = $this->getExtension('Atom')->getDateModified();
+        }
+
+        if (!$date) {
+            $date = null;
+        }
+
+        $this->data['datemodified'] = $date;
+
+        return $this->data['datemodified'];
+    }
+
+    /**
+     * Get the entry description
+     *
+     * @return string
+     */
+    public function getDescription()
+    {
+        if (array_key_exists('description', $this->data)) {
+            return $this->data['description'];
+        }
+
+        $description = null;
+
+        if ($this->getType() !== Reader\Reader::TYPE_RSS_10
+            && $this->getType() !== Reader\Reader::TYPE_RSS_090
+        ) {
+            $description = $this->xpath->evaluate('string(' . $this->xpathQueryRss . '/description)');
+        } else {
+            $description = $this->xpath->evaluate('string(' . $this->xpathQueryRdf . '/rss:description)');
+        }
+
+        if (!$description) {
+            $description = $this->getExtension('DublinCore')->getDescription();
+        }
+
+        if (empty($description)) {
+            $description = $this->getExtension('Atom')->getDescription();
+        }
+
+        if (!$description) {
+            $description = null;
+        }
+
+        $this->data['description'] = $description;
+
+        return $this->data['description'];
+    }
+
+    /**
+     * Get the entry enclosure
+     * @return string
+     */
+    public function getEnclosure()
+    {
+        if (array_key_exists('enclosure', $this->data)) {
+            return $this->data['enclosure'];
+        }
+
+        $enclosure = null;
+
+        if ($this->getType() == Reader\Reader::TYPE_RSS_20) {
+            $nodeList = $this->xpath->query($this->xpathQueryRss . '/enclosure');
+
+            if ($nodeList->length > 0) {
+                $enclosure = new \stdClass();
+                $enclosure->url    = $nodeList->item(0)->getAttribute('url');
+                $enclosure->length = $nodeList->item(0)->getAttribute('length');
+                $enclosure->type   = $nodeList->item(0)->getAttribute('type');
+            }
+        }
+
+        if (!$enclosure) {
+            $enclosure = $this->getExtension('Atom')->getEnclosure();
+        }
+
+        $this->data['enclosure'] = $enclosure;
+
+        return $this->data['enclosure'];
+    }
+
+    /**
+     * Get the entry ID
+     *
+     * @return string
+     */
+    public function getId()
+    {
+        if (array_key_exists('id', $this->data)) {
+            return $this->data['id'];
+        }
+
+        $id = null;
+
+        if ($this->getType() !== Reader\Reader::TYPE_RSS_10
+            && $this->getType() !== Reader\Reader::TYPE_RSS_090
+        ) {
+            $id = $this->xpath->evaluate('string(' . $this->xpathQueryRss . '/guid)');
+        }
+
+        if (!$id) {
+            $id = $this->getExtension('DublinCore')->getId();
+        }
+
+        if (empty($id)) {
+            $id = $this->getExtension('Atom')->getId();
+        }
+
+        if (!$id) {
+            if ($this->getPermalink()) {
+                $id = $this->getPermalink();
+            } elseif ($this->getTitle()) {
+                $id = $this->getTitle();
+            } else {
+                $id = null;
+            }
+        }
+
+        $this->data['id'] = $id;
+
+        return $this->data['id'];
+    }
+
+    /**
+     * Get a specific link
+     *
+     * @param  int $index
+     * @return string
+     */
+    public function getLink($index = 0)
+    {
+        if (!array_key_exists('links', $this->data)) {
+            $this->getLinks();
+        }
+
+        if (isset($this->data['links'][$index])) {
+            return $this->data['links'][$index];
+        }
+
+        return null;
+    }
+
+    /**
+     * Get all links
+     *
+     * @return array
+     */
+    public function getLinks()
+    {
+        if (array_key_exists('links', $this->data)) {
+            return $this->data['links'];
+        }
+
+        $links = array();
+
+        if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
+            $this->getType() !== Reader\Reader::TYPE_RSS_090) {
+            $list = $this->xpath->query($this->xpathQueryRss . '//link');
+        } else {
+            $list = $this->xpath->query($this->xpathQueryRdf . '//rss:link');
+        }
+
+        if (!$list->length) {
+            $links = $this->getExtension('Atom')->getLinks();
+        } else {
+            foreach ($list as $link) {
+                $links[] = $link->nodeValue;
+            }
+        }
+
+        $this->data['links'] = $links;
+
+        return $this->data['links'];
+    }
+
+    /**
+     * Get all categories
+     *
+     * @return Reader\Collection\Category
+     */
+    public function getCategories()
+    {
+        if (array_key_exists('categories', $this->data)) {
+            return $this->data['categories'];
+        }
+
+        if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
+            $this->getType() !== Reader\Reader::TYPE_RSS_090) {
+            $list = $this->xpath->query($this->xpathQueryRss . '//category');
+        } else {
+            $list = $this->xpath->query($this->xpathQueryRdf . '//rss:category');
+        }
+
+        if ($list->length) {
+            $categoryCollection = new Reader\Collection\Category;
+            foreach ($list as $category) {
+                $categoryCollection[] = array(
+                    'term' => $category->nodeValue,
+                    'scheme' => $category->getAttribute('domain'),
+                    'label' => $category->nodeValue,
+                );
+            }
+        } else {
+            $categoryCollection = $this->getExtension('DublinCore')->getCategories();
+        }
+
+        if (count($categoryCollection) == 0) {
+            $categoryCollection = $this->getExtension('Atom')->getCategories();
+        }
+
+        $this->data['categories'] = $categoryCollection;
+
+        return $this->data['categories'];
+    }
+
+    /**
+     * Get a permalink to the entry
+     *
+     * @return string
+     */
+    public function getPermalink()
+    {
+        return $this->getLink(0);
+    }
+
+    /**
+     * Get the entry title
+     *
+     * @return string
+     */
+    public function getTitle()
+    {
+        if (array_key_exists('title', $this->data)) {
+            return $this->data['title'];
+        }
+
+        $title = null;
+
+        if ($this->getType() !== Reader\Reader::TYPE_RSS_10
+            && $this->getType() !== Reader\Reader::TYPE_RSS_090
+        ) {
+            $title = $this->xpath->evaluate('string(' . $this->xpathQueryRss . '/title)');
+        } else {
+            $title = $this->xpath->evaluate('string(' . $this->xpathQueryRdf . '/rss:title)');
+        }
+
+        if (!$title) {
+            $title = $this->getExtension('DublinCore')->getTitle();
+        }
+
+        if (!$title) {
+            $title = $this->getExtension('Atom')->getTitle();
+        }
+
+        if (!$title) {
+            $title = null;
+        }
+
+        $this->data['title'] = $title;
+
+        return $this->data['title'];
+    }
+
+    /**
+     * Get the number of comments/replies for current entry
+     *
+     * @return string|null
+     */
+    public function getCommentCount()
+    {
+        if (array_key_exists('commentcount', $this->data)) {
+            return $this->data['commentcount'];
+        }
+
+        $commentcount = $this->getExtension('Slash')->getCommentCount();
+
+        if (!$commentcount) {
+            $commentcount = $this->getExtension('Thread')->getCommentCount();
+        }
+
+        if (!$commentcount) {
+            $commentcount = $this->getExtension('Atom')->getCommentCount();
+        }
+
+        if (!$commentcount) {
+            $commentcount = null;
+        }
+
+        $this->data['commentcount'] = $commentcount;
+
+        return $this->data['commentcount'];
+    }
+
+    /**
+     * Returns a URI pointing to the HTML page where comments can be made on this entry
+     *
+     * @return string
+     */
+    public function getCommentLink()
+    {
+        if (array_key_exists('commentlink', $this->data)) {
+            return $this->data['commentlink'];
+        }
+
+        $commentlink = null;
+
+        if ($this->getType() !== Reader\Reader::TYPE_RSS_10
+            && $this->getType() !== Reader\Reader::TYPE_RSS_090
+        ) {
+            $commentlink = $this->xpath->evaluate('string(' . $this->xpathQueryRss . '/comments)');
+        }
+
+        if (!$commentlink) {
+            $commentlink = $this->getExtension('Atom')->getCommentLink();
+        }
+
+        if (!$commentlink) {
+            $commentlink = null;
+        }
+
+        $this->data['commentlink'] = $commentlink;
+
+        return $this->data['commentlink'];
+    }
+
+    /**
+     * Returns a URI pointing to a feed of all comments for this entry
+     *
+     * @return string
+     */
+    public function getCommentFeedLink()
+    {
+        if (array_key_exists('commentfeedlink', $this->data)) {
+            return $this->data['commentfeedlink'];
+        }
+
+        $commentfeedlink = $this->getExtension('WellFormedWeb')->getCommentFeedLink();
+
+        if (!$commentfeedlink) {
+            $commentfeedlink = $this->getExtension('Atom')->getCommentFeedLink('rss');
+        }
+
+        if (!$commentfeedlink) {
+            $commentfeedlink = $this->getExtension('Atom')->getCommentFeedLink('rdf');
+        }
+
+        if (!$commentfeedlink) {
+            $commentfeedlink = null;
+        }
+
+        $this->data['commentfeedlink'] = $commentfeedlink;
+
+        return $this->data['commentfeedlink'];
+    }
+
+    /**
+     * Set the XPath query (incl. on all Extensions)
+     *
+     * @param DOMXPath $xpath
+     * @return void
+     */
+    public function setXpath(DOMXPath $xpath)
+    {
+        parent::setXpath($xpath);
+        foreach ($this->extensions as $extension) {
+            $extension->setXpath($this->xpath);
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Exception/BadMethodCallException.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Exception/BadMethodCallException.php
new file mode 100644
index 000000000000..3994b0ceb692
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Exception/BadMethodCallException.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Exception;
+
+use Zend\Feed\Exception;
+
+class BadMethodCallException
+    extends Exception\BadMethodCallException
+    implements ExceptionInterface
+{}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Exception/ExceptionInterface.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Exception/ExceptionInterface.php
new file mode 100644
index 000000000000..09abac6d308d
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Exception/ExceptionInterface.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Exception;
+
+use Zend\Feed\Exception\ExceptionInterface as Exception;
+
+interface ExceptionInterface extends Exception
+{}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Exception/InvalidArgumentException.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Exception/InvalidArgumentException.php
new file mode 100644
index 000000000000..5860322ab528
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Exception/InvalidArgumentException.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Exception;
+
+use Zend\Feed\Exception;
+
+class InvalidArgumentException
+    extends Exception\InvalidArgumentException
+    implements ExceptionInterface
+{}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Exception/RuntimeException.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Exception/RuntimeException.php
new file mode 100644
index 000000000000..f0590fb43c8f
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Exception/RuntimeException.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Exception;
+
+use Zend\Feed\Exception;
+
+class RuntimeException
+    extends Exception\RuntimeException
+    implements ExceptionInterface
+{}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/AbstractEntry.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/AbstractEntry.php
new file mode 100644
index 000000000000..0f0333b9f520
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/AbstractEntry.php
@@ -0,0 +1,233 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Extension;
+
+use DOMDocument;
+use DOMElement;
+use DOMXPath;
+use Zend\Feed\Reader;
+
+abstract class AbstractEntry
+{
+    /**
+     * Feed entry data
+     *
+     * @var array
+     */
+    protected $data = array();
+
+    /**
+     * DOM document object
+     *
+     * @var DOMDocument
+     */
+    protected $domDocument = null;
+
+    /**
+     * Entry instance
+     *
+     * @var DOMElement
+     */
+    protected $entry = null;
+
+    /**
+     * Pointer to the current entry
+     *
+     * @var int
+     */
+    protected $entryKey = 0;
+
+    /**
+     * XPath object
+     *
+     * @var DOMXPath
+     */
+    protected $xpath = null;
+
+    /**
+     * XPath query
+     *
+     * @var string
+     */
+    protected $xpathPrefix = '';
+
+    /**
+     * Set the entry DOMElement
+     *
+     * Has side effect of setting the DOMDocument for the entry.
+     *
+     * @param  DOMElement $entry
+     * @return AbstractEntry
+     */
+    public function setEntryElement(DOMElement $entry)
+    {
+        $this->entry = $entry;
+        $this->domDocument = $entry->ownerDocument;
+        return $this;
+    }
+
+    /**
+     * Get the entry DOMElement
+     *
+     * @return DOMElement
+     */
+    public function getEntryElement()
+    {
+        return $this->entry;
+    }
+
+    /**
+     * Set the entry key
+     *
+     * @param  string $entryKey
+     * @return AbstractEntry
+     */
+    public function setEntryKey($entryKey)
+    {
+        $this->entryKey = $entryKey;
+        return $this;
+    }
+
+    /**
+     * Get the DOM
+     *
+     * @return DOMDocument
+     */
+    public function getDomDocument()
+    {
+        return $this->domDocument;
+    }
+
+    /**
+     * Get the Entry's encoding
+     *
+     * @return string
+     */
+    public function getEncoding()
+    {
+        $assumed = $this->getDomDocument()->encoding;
+        return $assumed;
+    }
+
+    /**
+     * Set the entry type
+     *
+     * Has side effect of setting xpath prefix
+     *
+     * @param  string $type
+     * @return AbstractEntry
+     */
+    public function setType($type)
+    {
+        if (null === $type) {
+            $this->data['type'] = null;
+            return $this;
+        }
+
+        $this->data['type'] = $type;
+        if ($type === Reader\Reader::TYPE_RSS_10
+            || $type === Reader\Reader::TYPE_RSS_090
+        ) {
+            $this->setXpathPrefix('//rss:item[' . ($this->entryKey + 1) . ']');
+            return $this;
+        }
+
+        if ($type === Reader\Reader::TYPE_ATOM_10
+            || $type === Reader\Reader::TYPE_ATOM_03
+        ) {
+            $this->setXpathPrefix('//atom:entry[' . ($this->entryKey + 1) . ']');
+            return $this;
+        }
+
+        $this->setXpathPrefix('//item[' . ($this->entryKey + 1) . ']');
+        return $this;
+    }
+
+    /**
+     * Get the entry type
+     *
+     * @return string
+     */
+    public function getType()
+    {
+        $type = $this->data['type'];
+        if ($type === null) {
+            $type = Reader\Reader::detectType($this->getEntryElement(), true);
+            $this->setType($type);
+        }
+
+        return $type;
+    }
+
+    /**
+     * Set the XPath query
+     *
+     * @param  DOMXPath $xpath
+     * @return AbstractEntry
+     */
+    public function setXpath(DOMXPath $xpath)
+    {
+        $this->xpath = $xpath;
+        $this->registerNamespaces();
+        return $this;
+    }
+
+    /**
+     * Get the XPath query object
+     *
+     * @return DOMXPath
+     */
+    public function getXpath()
+    {
+        if (!$this->xpath) {
+            $this->setXpath(new DOMXPath($this->getDomDocument()));
+        }
+        return $this->xpath;
+    }
+
+    /**
+     * Serialize the entry to an array
+     *
+     * @return array
+     */
+    public function toArray()
+    {
+        return $this->data;
+    }
+
+    /**
+     * Get the XPath prefix
+     *
+     * @return string
+     */
+    public function getXpathPrefix()
+    {
+        return $this->xpathPrefix;
+    }
+
+    /**
+     * Set the XPath prefix
+     *
+     * @param  string $prefix
+     * @return AbstractEntry
+     */
+    public function setXpathPrefix($prefix)
+    {
+        $this->xpathPrefix = $prefix;
+        return $this;
+    }
+
+    /**
+     * Register XML namespaces
+     *
+     * @return void
+     */
+    abstract protected function registerNamespaces();
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/AbstractFeed.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/AbstractFeed.php
new file mode 100644
index 000000000000..75089253602d
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/AbstractFeed.php
@@ -0,0 +1,176 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Extension;
+
+use DOMDocument;
+use DOMXPath;
+use Zend\Feed\Reader;
+
+abstract class AbstractFeed
+{
+    /**
+     * Parsed feed data
+     *
+     * @var array
+     */
+    protected $data = array();
+
+    /**
+     * Parsed feed data in the shape of a DOMDocument
+     *
+     * @var DOMDocument
+     */
+    protected $domDocument = null;
+
+    /**
+     * The base XPath query used to retrieve feed data
+     *
+     * @var DOMXPath
+     */
+    protected $xpath = null;
+
+    /**
+     * The XPath prefix
+     *
+     * @var string
+     */
+    protected $xpathPrefix = '';
+
+    /**
+     * Set the DOM document
+     *
+     * @param  DOMDocument $dom
+     * @return AbstractFeed
+     */
+    public function setDomDocument(DOMDocument $dom)
+    {
+        $this->domDocument = $dom;
+        return $this;
+    }
+
+    /**
+     * Get the DOM
+     *
+     * @return DOMDocument
+     */
+    public function getDomDocument()
+    {
+        return $this->domDocument;
+    }
+
+    /**
+     * Get the Feed's encoding
+     *
+     * @return string
+     */
+    public function getEncoding()
+    {
+        $assumed = $this->getDomDocument()->encoding;
+        return $assumed;
+    }
+
+    /**
+     * Set the feed type
+     *
+     * @param  string $type
+     * @return AbstractFeed
+     */
+    public function setType($type)
+    {
+        $this->data['type'] = $type;
+        return $this;
+    }
+
+    /**
+     * Get the feed type
+     *
+     * If null, it will attempt to autodetect the type.
+     *
+     * @return string
+     */
+    public function getType()
+    {
+        $type = $this->data['type'];
+        if (null === $type) {
+            $type = Reader\Reader::detectType($this->getDomDocument());
+            $this->setType($type);
+        }
+        return $type;
+    }
+
+
+    /**
+     * Return the feed as an array
+     *
+     * @return array
+     */
+    public function toArray() // untested
+    {
+        return $this->data;
+    }
+
+    /**
+     * Set the XPath query
+     *
+     * @param  DOMXPath $xpath
+     * @return AbstractEntry
+     */
+    public function setXpath(DOMXPath $xpath = null)
+    {
+        if (null === $xpath) {
+            $this->xpath = null;
+            return $this;
+        }
+
+        $this->xpath = $xpath;
+        $this->registerNamespaces();
+        return $this;
+    }
+
+    /**
+     * Get the DOMXPath object
+     *
+     * @return string
+     */
+    public function getXpath()
+    {
+        if (null === $this->xpath) {
+            $this->setXpath(new DOMXPath($this->getDomDocument()));
+        }
+
+        return $this->xpath;
+    }
+
+    /**
+     * Get the XPath prefix
+     *
+     * @return string
+     */
+    public function getXpathPrefix()
+    {
+        return $this->xpathPrefix;
+    }
+
+    /**
+     * Set the XPath prefix
+     *
+     * @param string $prefix
+     * @return void
+     */
+    public function setXpathPrefix($prefix)
+    {
+        $this->xpathPrefix = $prefix;
+    }
+
+    /**
+     * Register the default namespaces for the current feed format
+     */
+    abstract protected function registerNamespaces();
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Atom/Entry.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Atom/Entry.php
new file mode 100644
index 000000000000..d68577cdf72d
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Atom/Entry.php
@@ -0,0 +1,628 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Extension\Atom;
+
+use DateTime;
+use DOMDocument;
+use DOMElement;
+use stdClass;
+use Zend\Feed\Reader;
+use Zend\Feed\Reader\Collection;
+use Zend\Feed\Reader\Extension;
+use Zend\Feed\Uri;
+
+class Entry extends Extension\AbstractEntry
+{
+    /**
+     * Get the specified author
+     *
+     * @param  int $index
+     * @return string|null
+     */
+    public function getAuthor($index = 0)
+    {
+        $authors = $this->getAuthors();
+
+        if (isset($authors[$index])) {
+            return $authors[$index];
+        }
+
+        return null;
+    }
+
+    /**
+     * Get an array with feed authors
+     *
+     * @return Collection\Author
+     */
+    public function getAuthors()
+    {
+        if (array_key_exists('authors', $this->data)) {
+            return $this->data['authors'];
+        }
+
+        $authors = array();
+        $list = $this->getXpath()->query($this->getXpathPrefix() . '//atom:author');
+
+        if (!$list->length) {
+            /**
+             * TODO: Limit query to feed level els only!
+             */
+            $list = $this->getXpath()->query('//atom:author');
+        }
+
+        if ($list->length) {
+            foreach ($list as $author) {
+                $author = $this->getAuthorFromElement($author);
+                if (!empty($author)) {
+                    $authors[] = $author;
+                }
+            }
+        }
+
+        if (count($authors) == 0) {
+            $authors = new Collection\Author();
+        } else {
+            $authors = new Collection\Author(
+                Reader\Reader::arrayUnique($authors)
+            );
+        }
+
+        $this->data['authors'] = $authors;
+        return $this->data['authors'];
+    }
+
+    /**
+     * Get the entry content
+     *
+     * @return string
+     */
+    public function getContent()
+    {
+        if (array_key_exists('content', $this->data)) {
+            return $this->data['content'];
+        }
+
+        $content = null;
+
+        $el = $this->getXpath()->query($this->getXpathPrefix() . '/atom:content');
+        if ($el->length > 0) {
+            $el = $el->item(0);
+            $type = $el->getAttribute('type');
+            switch ($type) {
+                case '':
+                case 'text':
+                case 'text/plain':
+                case 'html':
+                case 'text/html':
+                    $content = $el->nodeValue;
+                break;
+                case 'xhtml':
+                    $this->getXpath()->registerNamespace('xhtml', 'http://www.w3.org/1999/xhtml');
+                    $xhtml = $this->getXpath()->query(
+                        $this->getXpathPrefix() . '/atom:content/xhtml:div'
+                    )->item(0);
+                    $d = new DOMDocument('1.0', $this->getEncoding());
+                    $xhtmls = $d->importNode($xhtml, true);
+                    $d->appendChild($xhtmls);
+                    $content = $this->collectXhtml(
+                        $d->saveXML(),
+                        $d->lookupPrefix('http://www.w3.org/1999/xhtml')
+                    );
+                break;
+            }
+        }
+
+        if (!$content) {
+            $content = $this->getDescription();
+        }
+
+        $this->data['content'] = trim($content);
+
+        return $this->data['content'];
+    }
+
+    /**
+     * Parse out XHTML to remove the namespacing
+     *
+     * @param $xhtml
+     * @param $prefix
+     * @return mixed
+     */
+    protected function collectXhtml($xhtml, $prefix)
+    {
+        if (!empty($prefix)) $prefix = $prefix . ':';
+        $matches = array(
+            "/<\?xml[^<]*>[^<]*<" . $prefix . "div[^<]*/",
+            "/<\/" . $prefix . "div>\s*$/"
+        );
+        $xhtml = preg_replace($matches, '', $xhtml);
+        if (!empty($prefix)) {
+            $xhtml = preg_replace("/(<[\/]?)" . $prefix . "([a-zA-Z]+)/", '$1$2', $xhtml);
+        }
+        return $xhtml;
+    }
+
+    /**
+     * Get the entry creation date
+     *
+     * @return string
+     */
+    public function getDateCreated()
+    {
+        if (array_key_exists('datecreated', $this->data)) {
+            return $this->data['datecreated'];
+        }
+
+        $date = null;
+
+        if ($this->getAtomType() === Reader\Reader::TYPE_ATOM_03) {
+            $dateCreated = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/atom:created)');
+        } else {
+            $dateCreated = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/atom:published)');
+        }
+
+        if ($dateCreated) {
+            $date = new DateTime($dateCreated);
+        }
+
+        $this->data['datecreated'] = $date;
+
+        return $this->data['datecreated'];
+    }
+
+    /**
+     * Get the entry modification date
+     *
+     * @return string
+     */
+    public function getDateModified()
+    {
+        if (array_key_exists('datemodified', $this->data)) {
+            return $this->data['datemodified'];
+        }
+
+        $date = null;
+
+        if ($this->getAtomType() === Reader\Reader::TYPE_ATOM_03) {
+            $dateModified = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/atom:modified)');
+        } else {
+            $dateModified = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/atom:updated)');
+        }
+
+        if ($dateModified) {
+            $date = new DateTime($dateModified);
+        }
+
+        $this->data['datemodified'] = $date;
+
+        return $this->data['datemodified'];
+    }
+
+    /**
+     * Get the entry description
+     *
+     * @return string
+     */
+    public function getDescription()
+    {
+        if (array_key_exists('description', $this->data)) {
+            return $this->data['description'];
+        }
+
+        $description = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/atom:summary)');
+
+        if (!$description) {
+            $description = null;
+        }
+
+        $this->data['description'] = $description;
+
+        return $this->data['description'];
+    }
+
+    /**
+     * Get the entry enclosure
+     *
+     * @return string
+     */
+    public function getEnclosure()
+    {
+        if (array_key_exists('enclosure', $this->data)) {
+            return $this->data['enclosure'];
+        }
+
+        $enclosure = null;
+
+        $nodeList = $this->getXpath()->query($this->getXpathPrefix() . '/atom:link[@rel="enclosure"]');
+
+        if ($nodeList->length > 0) {
+            $enclosure         = new stdClass();
+            $enclosure->url    = $nodeList->item(0)->getAttribute('href');
+            $enclosure->length = $nodeList->item(0)->getAttribute('length');
+            $enclosure->type   = $nodeList->item(0)->getAttribute('type');
+        }
+
+        $this->data['enclosure'] = $enclosure;
+
+        return $this->data['enclosure'];
+    }
+
+    /**
+     * Get the entry ID
+     *
+     * @return string
+     */
+    public function getId()
+    {
+        if (array_key_exists('id', $this->data)) {
+            return $this->data['id'];
+        }
+
+        $id = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/atom:id)');
+
+        if (!$id) {
+            if ($this->getPermalink()) {
+                $id = $this->getPermalink();
+            } elseif ($this->getTitle()) {
+                $id = $this->getTitle();
+            } else {
+                $id = null;
+            }
+        }
+
+        $this->data['id'] = $id;
+
+        return $this->data['id'];
+    }
+
+    /**
+     * Get the base URI of the feed (if set).
+     *
+     * @return string|null
+     */
+    public function getBaseUrl()
+    {
+        if (array_key_exists('baseUrl', $this->data)) {
+            return $this->data['baseUrl'];
+        }
+
+        $baseUrl = $this->getXpath()->evaluate('string('
+            . $this->getXpathPrefix() . '/@xml:base[1]'
+        . ')');
+
+        if (!$baseUrl) {
+            $baseUrl = $this->getXpath()->evaluate('string(//@xml:base[1])');
+        }
+
+        if (!$baseUrl) {
+            $baseUrl = null;
+        }
+
+        $this->data['baseUrl'] = $baseUrl;
+
+        return $this->data['baseUrl'];
+    }
+
+    /**
+     * Get a specific link
+     *
+     * @param  int $index
+     * @return string
+     */
+    public function getLink($index = 0)
+    {
+        if (!array_key_exists('links', $this->data)) {
+            $this->getLinks();
+        }
+
+        if (isset($this->data['links'][$index])) {
+            return $this->data['links'][$index];
+        }
+
+        return null;
+    }
+
+    /**
+     * Get all links
+     *
+     * @return array
+     */
+    public function getLinks()
+    {
+        if (array_key_exists('links', $this->data)) {
+            return $this->data['links'];
+        }
+
+        $links = array();
+
+        $list = $this->getXpath()->query(
+            $this->getXpathPrefix() . '//atom:link[@rel="alternate"]/@href' . '|' .
+            $this->getXpathPrefix() . '//atom:link[not(@rel)]/@href'
+        );
+
+        if ($list->length) {
+            foreach ($list as $link) {
+                $links[] = $this->absolutiseUri($link->value);
+            }
+        }
+
+        $this->data['links'] = $links;
+
+        return $this->data['links'];
+    }
+
+    /**
+     * Get a permalink to the entry
+     *
+     * @return string
+     */
+    public function getPermalink()
+    {
+        return $this->getLink(0);
+    }
+
+    /**
+     * Get the entry title
+     *
+     * @return string
+     */
+    public function getTitle()
+    {
+        if (array_key_exists('title', $this->data)) {
+            return $this->data['title'];
+        }
+
+        $title = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/atom:title)');
+
+        if (!$title) {
+            $title = null;
+        }
+
+        $this->data['title'] = $title;
+
+        return $this->data['title'];
+    }
+
+    /**
+     * Get the number of comments/replies for current entry
+     *
+     * @return int
+     */
+    public function getCommentCount()
+    {
+        if (array_key_exists('commentcount', $this->data)) {
+            return $this->data['commentcount'];
+        }
+
+        $count = null;
+
+        $this->getXpath()->registerNamespace('thread10', 'http://purl.org/syndication/thread/1.0');
+        $list = $this->getXpath()->query(
+            $this->getXpathPrefix() . '//atom:link[@rel="replies"]/@thread10:count'
+        );
+
+        if ($list->length) {
+            $count = $list->item(0)->value;
+        }
+
+        $this->data['commentcount'] = $count;
+
+        return $this->data['commentcount'];
+    }
+
+    /**
+     * Returns a URI pointing to the HTML page where comments can be made on this entry
+     *
+     * @return string
+     */
+    public function getCommentLink()
+    {
+        if (array_key_exists('commentlink', $this->data)) {
+            return $this->data['commentlink'];
+        }
+
+        $link = null;
+
+        $list = $this->getXpath()->query(
+            $this->getXpathPrefix() . '//atom:link[@rel="replies" and @type="text/html"]/@href'
+        );
+
+        if ($list->length) {
+            $link = $list->item(0)->value;
+            $link = $this->absolutiseUri($link);
+        }
+
+        $this->data['commentlink'] = $link;
+
+        return $this->data['commentlink'];
+    }
+
+    /**
+     * Returns a URI pointing to a feed of all comments for this entry
+     *
+     * @param string $type
+     * @return string
+     */
+    public function getCommentFeedLink($type = 'atom')
+    {
+        if (array_key_exists('commentfeedlink', $this->data)) {
+            return $this->data['commentfeedlink'];
+        }
+
+        $link = null;
+
+        $list = $this->getXpath()->query(
+            $this->getXpathPrefix() . '//atom:link[@rel="replies" and @type="application/' . $type.'+xml"]/@href'
+        );
+
+        if ($list->length) {
+            $link = $list->item(0)->value;
+            $link = $this->absolutiseUri($link);
+        }
+
+        $this->data['commentfeedlink'] = $link;
+
+        return $this->data['commentfeedlink'];
+    }
+
+    /**
+     * Get all categories
+     *
+     * @return Collection\Category
+     */
+    public function getCategories()
+    {
+        if (array_key_exists('categories', $this->data)) {
+            return $this->data['categories'];
+        }
+
+        if ($this->getAtomType() == Reader\Reader::TYPE_ATOM_10) {
+            $list = $this->getXpath()->query($this->getXpathPrefix() . '//atom:category');
+        } else {
+            /**
+             * Since Atom 0.3 did not support categories, it would have used the
+             * Dublin Core extension. However there is a small possibility Atom 0.3
+             * may have been retrofitted to use Atom 1.0 instead.
+             */
+            $this->getXpath()->registerNamespace('atom10', Reader\Reader::NAMESPACE_ATOM_10);
+            $list = $this->getXpath()->query($this->getXpathPrefix() . '//atom10:category');
+        }
+
+        if ($list->length) {
+            $categoryCollection = new Collection\Category;
+            foreach ($list as $category) {
+                $categoryCollection[] = array(
+                    'term' => $category->getAttribute('term'),
+                    'scheme' => $category->getAttribute('scheme'),
+                    'label' => $category->getAttribute('label')
+                );
+            }
+        } else {
+            return new Collection\Category;
+        }
+
+        $this->data['categories'] = $categoryCollection;
+
+        return $this->data['categories'];
+    }
+
+    /**
+     * Get source feed metadata from the entry
+     *
+     * @return Reader\Feed\Atom\Source|null
+     */
+    public function getSource()
+    {
+        if (array_key_exists('source', $this->data)) {
+            return $this->data['source'];
+        }
+
+        $source = null;
+        // TODO: Investigate why _getAtomType() fails here. Is it even needed?
+        if ($this->getType() == Reader\Reader::TYPE_ATOM_10) {
+            $list = $this->getXpath()->query($this->getXpathPrefix() . '/atom:source[1]');
+            if ($list->length) {
+                $element = $list->item(0);
+                $source = new Reader\Feed\Atom\Source($element, $this->getXpathPrefix());
+            }
+        }
+
+        $this->data['source'] = $source;
+        return $this->data['source'];
+    }
+
+    /**
+     *  Attempt to absolutise the URI, i.e. if a relative URI apply the
+     *  xml:base value as a prefix to turn into an absolute URI.
+     *
+     * @param $link
+     * @return string
+     */
+    protected function absolutiseUri($link)
+    {
+        if (!Uri::factory($link)->isAbsolute()) {
+            if ($this->getBaseUrl() !== null) {
+                $link = $this->getBaseUrl() . $link;
+                if (!Uri::factory($link)->isValid()) {
+                    $link = null;
+                }
+            }
+        }
+        return $link;
+    }
+
+    /**
+     * Get an author entry
+     *
+     * @param DOMElement $element
+     * @return string
+     */
+    protected function getAuthorFromElement(DOMElement $element)
+    {
+        $author = array();
+
+        $emailNode = $element->getElementsByTagName('email');
+        $nameNode  = $element->getElementsByTagName('name');
+        $uriNode   = $element->getElementsByTagName('uri');
+
+        if ($emailNode->length && strlen($emailNode->item(0)->nodeValue) > 0) {
+            $author['email'] = $emailNode->item(0)->nodeValue;
+        }
+
+        if ($nameNode->length && strlen($nameNode->item(0)->nodeValue) > 0) {
+            $author['name'] = $nameNode->item(0)->nodeValue;
+        }
+
+        if ($uriNode->length && strlen($uriNode->item(0)->nodeValue) > 0) {
+            $author['uri'] = $uriNode->item(0)->nodeValue;
+        }
+
+        if (empty($author)) {
+            return null;
+        }
+        return $author;
+    }
+
+    /**
+     * Register the default namespaces for the current feed format
+     */
+    protected function registerNamespaces()
+    {
+        switch ($this->getAtomType()) {
+            case Reader\Reader::TYPE_ATOM_03:
+                $this->getXpath()->registerNamespace('atom', Reader\Reader::NAMESPACE_ATOM_03);
+                break;
+            default:
+                $this->getXpath()->registerNamespace('atom', Reader\Reader::NAMESPACE_ATOM_10);
+                break;
+        }
+    }
+
+    /**
+     * Detect the presence of any Atom namespaces in use
+     *
+     * @return string
+     */
+    protected function getAtomType()
+    {
+        $dom = $this->getDomDocument();
+        $prefixAtom03 = $dom->lookupPrefix(Reader\Reader::NAMESPACE_ATOM_03);
+        $prefixAtom10 = $dom->lookupPrefix(Reader\Reader::NAMESPACE_ATOM_10);
+        if ($dom->isDefaultNamespace(Reader\Reader::NAMESPACE_ATOM_03)
+        || !empty($prefixAtom03)) {
+            return Reader\Reader::TYPE_ATOM_03;
+        }
+        if ($dom->isDefaultNamespace(Reader\Reader::NAMESPACE_ATOM_10)
+        || !empty($prefixAtom10)) {
+            return Reader\Reader::TYPE_ATOM_10;
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Atom/Feed.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Atom/Feed.php
new file mode 100644
index 000000000000..83e9ccae7c89
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Atom/Feed.php
@@ -0,0 +1,536 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Extension\Atom;
+
+use DateTime;
+use DOMElement;
+use Zend\Feed\Reader;
+use Zend\Feed\Reader\Collection;
+use Zend\Feed\Reader\Extension;
+use Zend\Feed\Uri;
+
+class Feed extends Extension\AbstractFeed
+{
+    /**
+     * Get a single author
+     *
+     * @param  int $index
+     * @return string|null
+     */
+    public function getAuthor($index = 0)
+    {
+        $authors = $this->getAuthors();
+
+        if (isset($authors[$index])) {
+            return $authors[$index];
+        }
+
+        return null;
+    }
+
+    /**
+     * Get an array with feed authors
+     *
+     * @return Collection\Author
+     */
+    public function getAuthors()
+    {
+        if (array_key_exists('authors', $this->data)) {
+            return $this->data['authors'];
+        }
+
+        $list = $this->xpath->query('//atom:author');
+
+        $authors = array();
+
+        if ($list->length) {
+            foreach ($list as $author) {
+                $author = $this->getAuthorFromElement($author);
+                if (!empty($author)) {
+                    $authors[] = $author;
+                }
+            }
+        }
+
+        if (count($authors) == 0) {
+            $authors = new Collection\Author();
+        } else {
+            $authors = new Collection\Author(
+                Reader\Reader::arrayUnique($authors)
+            );
+        }
+
+        $this->data['authors'] = $authors;
+
+        return $this->data['authors'];
+    }
+
+    /**
+     * Get the copyright entry
+     *
+     * @return string|null
+     */
+    public function getCopyright()
+    {
+        if (array_key_exists('copyright', $this->data)) {
+            return $this->data['copyright'];
+        }
+
+        $copyright = null;
+
+        if ($this->getType() === Reader\Reader::TYPE_ATOM_03) {
+            $copyright = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:copyright)');
+        } else {
+            $copyright = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:rights)');
+        }
+
+        if (!$copyright) {
+            $copyright = null;
+        }
+
+        $this->data['copyright'] = $copyright;
+
+        return $this->data['copyright'];
+    }
+
+    /**
+     * Get the feed creation date
+     *
+     * @return DateTime|null
+     */
+    public function getDateCreated()
+    {
+        if (array_key_exists('datecreated', $this->data)) {
+            return $this->data['datecreated'];
+        }
+
+        $date = null;
+
+        if ($this->getType() === Reader\Reader::TYPE_ATOM_03) {
+            $dateCreated = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:created)');
+        } else {
+            $dateCreated = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:published)');
+        }
+
+        if ($dateCreated) {
+            $date = new DateTime($dateCreated);
+        }
+
+        $this->data['datecreated'] = $date;
+
+        return $this->data['datecreated'];
+    }
+
+    /**
+     * Get the feed modification date
+     *
+     * @return DateTime|null
+     */
+    public function getDateModified()
+    {
+        if (array_key_exists('datemodified', $this->data)) {
+            return $this->data['datemodified'];
+        }
+
+        $date = null;
+
+        if ($this->getType() === Reader\Reader::TYPE_ATOM_03) {
+            $dateModified = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:modified)');
+        } else {
+            $dateModified = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:updated)');
+        }
+
+        if ($dateModified) {
+            $date = new DateTime($dateModified);
+        }
+
+        $this->data['datemodified'] = $date;
+
+        return $this->data['datemodified'];
+    }
+
+    /**
+     * Get the feed description
+     *
+     * @return string|null
+     */
+    public function getDescription()
+    {
+        if (array_key_exists('description', $this->data)) {
+            return $this->data['description'];
+        }
+
+        $description = null;
+
+        if ($this->getType() === Reader\Reader::TYPE_ATOM_03) {
+            $description = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:tagline)');
+        } else {
+            $description = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:subtitle)');
+        }
+
+        if (!$description) {
+            $description = null;
+        }
+
+        $this->data['description'] = $description;
+
+        return $this->data['description'];
+    }
+
+    /**
+     * Get the feed generator entry
+     *
+     * @return string|null
+     */
+    public function getGenerator()
+    {
+        if (array_key_exists('generator', $this->data)) {
+            return $this->data['generator'];
+        }
+        // TODO: Add uri support
+        $generator = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:generator)');
+
+        if (!$generator) {
+            $generator = null;
+        }
+
+        $this->data['generator'] = $generator;
+
+        return $this->data['generator'];
+    }
+
+    /**
+     * Get the feed ID
+     *
+     * @return string|null
+     */
+    public function getId()
+    {
+        if (array_key_exists('id', $this->data)) {
+            return $this->data['id'];
+        }
+
+        $id = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:id)');
+
+        if (!$id) {
+            if ($this->getLink()) {
+                $id = $this->getLink();
+            } elseif ($this->getTitle()) {
+                $id = $this->getTitle();
+            } else {
+                $id = null;
+            }
+        }
+
+        $this->data['id'] = $id;
+
+        return $this->data['id'];
+    }
+
+    /**
+     * Get the feed language
+     *
+     * @return string|null
+     */
+    public function getLanguage()
+    {
+        if (array_key_exists('language', $this->data)) {
+            return $this->data['language'];
+        }
+
+        $language = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:lang)');
+
+        if (!$language) {
+            $language = $this->xpath->evaluate('string(//@xml:lang[1])');
+        }
+
+        if (!$language) {
+            $language = null;
+        }
+
+        $this->data['language'] = $language;
+
+        return $this->data['language'];
+    }
+
+    /**
+     * Get the feed image
+     *
+     * @return array|null
+     */
+    public function getImage()
+    {
+        if (array_key_exists('image', $this->data)) {
+            return $this->data['image'];
+        }
+
+        $imageUrl = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:logo)');
+
+        if (!$imageUrl) {
+            $image = null;
+        } else {
+            $image = array('uri' => $imageUrl);
+        }
+
+        $this->data['image'] = $image;
+
+        return $this->data['image'];
+    }
+
+    /**
+     * Get the base URI of the feed (if set).
+     *
+     * @return string|null
+     */
+    public function getBaseUrl()
+    {
+        if (array_key_exists('baseUrl', $this->data)) {
+            return $this->data['baseUrl'];
+        }
+
+        $baseUrl = $this->xpath->evaluate('string(//@xml:base[1])');
+
+        if (!$baseUrl) {
+            $baseUrl = null;
+        }
+        $this->data['baseUrl'] = $baseUrl;
+
+        return $this->data['baseUrl'];
+    }
+
+    /**
+     * Get a link to the source website
+     *
+     * @return string|null
+     */
+    public function getLink()
+    {
+        if (array_key_exists('link', $this->data)) {
+            return $this->data['link'];
+        }
+
+        $link = null;
+
+        $list = $this->xpath->query(
+            $this->getXpathPrefix() . '/atom:link[@rel="alternate"]/@href' . '|' .
+            $this->getXpathPrefix() . '/atom:link[not(@rel)]/@href'
+        );
+
+        if ($list->length) {
+            $link = $list->item(0)->nodeValue;
+            $link = $this->absolutiseUri($link);
+        }
+
+        $this->data['link'] = $link;
+
+        return $this->data['link'];
+    }
+
+    /**
+     * Get a link to the feed's XML Url
+     *
+     * @return string|null
+     */
+    public function getFeedLink()
+    {
+        if (array_key_exists('feedlink', $this->data)) {
+            return $this->data['feedlink'];
+        }
+
+        $link = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:link[@rel="self"]/@href)');
+
+        $link = $this->absolutiseUri($link);
+
+        $this->data['feedlink'] = $link;
+
+        return $this->data['feedlink'];
+    }
+
+    /**
+     * Get an array of any supported Pusubhubbub endpoints
+     *
+     * @return array|null
+     */
+    public function getHubs()
+    {
+        if (array_key_exists('hubs', $this->data)) {
+            return $this->data['hubs'];
+        }
+        $hubs = array();
+
+        $list = $this->xpath->query($this->getXpathPrefix()
+            . '//atom:link[@rel="hub"]/@href');
+
+        if ($list->length) {
+            foreach ($list as $uri) {
+                $hubs[] = $this->absolutiseUri($uri->nodeValue);
+            }
+        } else {
+            $hubs = null;
+        }
+
+        $this->data['hubs'] = $hubs;
+
+        return $this->data['hubs'];
+    }
+
+    /**
+     * Get the feed title
+     *
+     * @return string|null
+     */
+    public function getTitle()
+    {
+        if (array_key_exists('title', $this->data)) {
+            return $this->data['title'];
+        }
+
+        $title = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:title)');
+
+        if (!$title) {
+            $title = null;
+        }
+
+        $this->data['title'] = $title;
+
+        return $this->data['title'];
+    }
+
+    /**
+     * Get all categories
+     *
+     * @return Collection\Category
+     */
+    public function getCategories()
+    {
+        if (array_key_exists('categories', $this->data)) {
+            return $this->data['categories'];
+        }
+
+        if ($this->getType() == Reader\Reader::TYPE_ATOM_10) {
+            $list = $this->xpath->query($this->getXpathPrefix() . '/atom:category');
+        } else {
+            /**
+             * Since Atom 0.3 did not support categories, it would have used the
+             * Dublin Core extension. However there is a small possibility Atom 0.3
+             * may have been retrofittied to use Atom 1.0 instead.
+             */
+            $this->xpath->registerNamespace('atom10', Reader\Reader::NAMESPACE_ATOM_10);
+            $list = $this->xpath->query($this->getXpathPrefix() . '/atom10:category');
+        }
+
+        if ($list->length) {
+            $categoryCollection = new Collection\Category;
+            foreach ($list as $category) {
+                $categoryCollection[] = array(
+                    'term' => $category->getAttribute('term'),
+                    'scheme' => $category->getAttribute('scheme'),
+                    'label' => $category->getAttribute('label')
+                );
+            }
+        } else {
+            return new Collection\Category;
+        }
+
+        $this->data['categories'] = $categoryCollection;
+
+        return $this->data['categories'];
+    }
+
+    /**
+     * Get an author entry in RSS format
+     *
+     * @param  DOMElement $element
+     * @return string
+     */
+    protected function getAuthorFromElement(DOMElement $element)
+    {
+        $author = array();
+
+        $emailNode = $element->getElementsByTagName('email');
+        $nameNode  = $element->getElementsByTagName('name');
+        $uriNode   = $element->getElementsByTagName('uri');
+
+        if ($emailNode->length && strlen($emailNode->item(0)->nodeValue) > 0) {
+            $author['email'] = $emailNode->item(0)->nodeValue;
+        }
+
+        if ($nameNode->length && strlen($nameNode->item(0)->nodeValue) > 0) {
+            $author['name'] = $nameNode->item(0)->nodeValue;
+        }
+
+        if ($uriNode->length && strlen($uriNode->item(0)->nodeValue) > 0) {
+            $author['uri'] = $uriNode->item(0)->nodeValue;
+        }
+
+        if (empty($author)) {
+            return null;
+        }
+        return $author;
+    }
+
+    /**
+     *  Attempt to absolutise the URI, i.e. if a relative URI apply the
+     *  xml:base value as a prefix to turn into an absolute URI.
+     */
+    protected function absolutiseUri($link)
+    {
+        if (!Uri::factory($link)->isAbsolute()) {
+            if ($this->getBaseUrl() !== null) {
+                $link = $this->getBaseUrl() . $link;
+                if (!Uri::factory($link)->isValid()) {
+                    $link = null;
+                }
+            }
+        }
+        return $link;
+    }
+
+    /**
+     * Register the default namespaces for the current feed format
+     */
+    protected function registerNamespaces()
+    {
+        if ($this->getType() == Reader\Reader::TYPE_ATOM_10
+            || $this->getType() == Reader\Reader::TYPE_ATOM_03
+        ) {
+            return; // pre-registered at Feed level
+        }
+        $atomDetected = $this->getAtomType();
+        switch ($atomDetected) {
+            case Reader\Reader::TYPE_ATOM_03:
+                $this->xpath->registerNamespace('atom', Reader\Reader::NAMESPACE_ATOM_03);
+                break;
+            default:
+                $this->xpath->registerNamespace('atom', Reader\Reader::NAMESPACE_ATOM_10);
+                break;
+        }
+    }
+
+    /**
+     * Detect the presence of any Atom namespaces in use
+     */
+    protected function getAtomType()
+    {
+        $dom = $this->getDomDocument();
+        $prefixAtom03 = $dom->lookupPrefix(Reader\Reader::NAMESPACE_ATOM_03);
+        $prefixAtom10 = $dom->lookupPrefix(Reader\Reader::NAMESPACE_ATOM_10);
+        if ($dom->isDefaultNamespace(Reader\Reader::NAMESPACE_ATOM_10)
+            || !empty($prefixAtom10)
+        ) {
+            return Reader\Reader::TYPE_ATOM_10;
+        }
+        if ($dom->isDefaultNamespace(Reader\Reader::NAMESPACE_ATOM_03)
+            || !empty($prefixAtom03)
+        ) {
+            return Reader\Reader::TYPE_ATOM_03;
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Content/Entry.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Content/Entry.php
new file mode 100644
index 000000000000..88fd850b25ab
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Content/Entry.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Extension\Content;
+
+use Zend\Feed\Reader;
+use Zend\Feed\Reader\Extension;
+
+class Entry extends Extension\AbstractEntry
+{
+
+    public function getContent()
+    {
+        if ($this->getType() !== Reader\Reader::TYPE_RSS_10
+            && $this->getType() !== Reader\Reader::TYPE_RSS_090
+        ) {
+            $content = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/content:encoded)');
+        } else {
+            $content = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/content:encoded)');
+        }
+        return $content;
+    }
+
+    /**
+     * Register RSS Content Module namespace
+     */
+    protected function registerNamespaces()
+    {
+        $this->xpath->registerNamespace('content', 'http://purl.org/rss/1.0/modules/content/');
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/CreativeCommons/Entry.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/CreativeCommons/Entry.php
new file mode 100644
index 000000000000..0352102c634d
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/CreativeCommons/Entry.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Extension\CreativeCommons;
+
+use Zend\Feed\Reader;
+use Zend\Feed\Reader\Extension;
+
+class Entry extends Extension\AbstractEntry
+{
+    /**
+     * Get the entry license
+     *
+     * @param int $index
+     * @return string|null
+     */
+    public function getLicense($index = 0)
+    {
+        $licenses = $this->getLicenses();
+
+        if (isset($licenses[$index])) {
+            return $licenses[$index];
+        }
+
+        return null;
+    }
+
+    /**
+     * Get the entry licenses
+     *
+     * @return array
+     */
+    public function getLicenses()
+    {
+        $name = 'licenses';
+        if (array_key_exists($name, $this->data)) {
+            return $this->data[$name];
+        }
+
+        $licenses = array();
+        $list = $this->xpath->evaluate($this->getXpathPrefix() . '//cc:license');
+
+        if ($list->length) {
+            foreach ($list as $license) {
+                    $licenses[] = $license->nodeValue;
+            }
+
+            $licenses = array_unique($licenses);
+        } else {
+            $cc = new Feed();
+            $licenses = $cc->getLicenses();
+        }
+
+        $this->data[$name] = $licenses;
+
+        return $this->data[$name];
+    }
+
+    /**
+     * Register Creative Commons namespaces
+     *
+     */
+    protected function registerNamespaces()
+    {
+        $this->xpath->registerNamespace('cc', 'http://backend.userland.com/creativeCommonsRssModule');
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/CreativeCommons/Feed.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/CreativeCommons/Feed.php
new file mode 100644
index 000000000000..d2a50496078d
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/CreativeCommons/Feed.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Extension\CreativeCommons;
+
+use Zend\Feed\Reader;
+use Zend\Feed\Reader\Extension;
+
+class Feed extends Extension\AbstractFeed
+{
+    /**
+     * Get the entry license
+     *
+     * @param int $index
+     * @return string|null
+     */
+    public function getLicense($index = 0)
+    {
+        $licenses = $this->getLicenses();
+
+        if (isset($licenses[$index])) {
+            return $licenses[$index];
+        }
+
+        return null;
+    }
+
+    /**
+     * Get the entry licenses
+     *
+     * @return array
+     */
+    public function getLicenses()
+    {
+        $name = 'licenses';
+        if (array_key_exists($name, $this->data)) {
+            return $this->data[$name];
+        }
+
+        $licenses = array();
+        $list = $this->xpath->evaluate('channel/cc:license');
+
+        if ($list->length) {
+            foreach ($list as $license) {
+                $licenses[] = $license->nodeValue;
+            }
+
+            $licenses = array_unique($licenses);
+        }
+
+        $this->data[$name] = $licenses;
+
+        return $this->data[$name];
+    }
+
+    /**
+     * Register Creative Commons namespaces
+     *
+     * @return void
+     */
+    protected function registerNamespaces()
+    {
+        $this->xpath->registerNamespace('cc', 'http://backend.userland.com/creativeCommonsRssModule');
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/DublinCore/Entry.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/DublinCore/Entry.php
new file mode 100644
index 000000000000..7ec5304e953c
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/DublinCore/Entry.php
@@ -0,0 +1,238 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Extension\DublinCore;
+
+use DateTime;
+use Zend\Feed\Reader;
+use Zend\Feed\Reader\Collection;
+use Zend\Feed\Reader\Extension;
+
+class Entry extends Extension\AbstractEntry
+{
+    /**
+     * Get an author entry
+     *
+     * @param int $index
+     * @return string
+     */
+    public function getAuthor($index = 0)
+    {
+        $authors = $this->getAuthors();
+
+        if (isset($authors[$index])) {
+            return $authors[$index];
+        }
+
+        return null;
+    }
+
+    /**
+     * Get an array with feed authors
+     *
+     * @return array
+     */
+    public function getAuthors()
+    {
+        if (array_key_exists('authors', $this->data)) {
+            return $this->data['authors'];
+        }
+
+        $authors = array();
+        $list = $this->getXpath()->evaluate($this->getXpathPrefix() . '//dc11:creator');
+
+        if (!$list->length) {
+            $list = $this->getXpath()->evaluate($this->getXpathPrefix() . '//dc10:creator');
+        }
+        if (!$list->length) {
+            $list = $this->getXpath()->evaluate($this->getXpathPrefix() . '//dc11:publisher');
+
+            if (!$list->length) {
+                $list = $this->getXpath()->evaluate($this->getXpathPrefix() . '//dc10:publisher');
+            }
+        }
+
+        if ($list->length) {
+            foreach ($list as $author) {
+                $authors[] = array(
+                    'name' => $author->nodeValue
+                );
+            }
+            $authors = new Collection\Author(
+                Reader\Reader::arrayUnique($authors)
+            );
+        } else {
+            $authors = null;
+        }
+
+        $this->data['authors'] = $authors;
+
+        return $this->data['authors'];
+    }
+
+    /**
+     * Get categories (subjects under DC)
+     *
+     * @return Collection\Category
+     */
+    public function getCategories()
+    {
+        if (array_key_exists('categories', $this->data)) {
+            return $this->data['categories'];
+        }
+
+        $list = $this->getXpath()->evaluate($this->getXpathPrefix() . '//dc11:subject');
+
+        if (!$list->length) {
+            $list = $this->getXpath()->evaluate($this->getXpathPrefix() . '//dc10:subject');
+        }
+
+        if ($list->length) {
+            $categoryCollection = new Collection\Category;
+            foreach ($list as $category) {
+                $categoryCollection[] = array(
+                    'term' => $category->nodeValue,
+                    'scheme' => null,
+                    'label' => $category->nodeValue,
+                );
+            }
+        } else {
+            $categoryCollection = new Collection\Category;
+        }
+
+        $this->data['categories'] = $categoryCollection;
+        return $this->data['categories'];
+    }
+
+
+    /**
+     * Get the entry content
+     *
+     * @return string
+     */
+    public function getContent()
+    {
+        return $this->getDescription();
+    }
+
+    /**
+     * Get the entry description
+     *
+     * @return string
+     */
+    public function getDescription()
+    {
+        if (array_key_exists('description', $this->data)) {
+            return $this->data['description'];
+        }
+
+        $description = null;
+        $description = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/dc11:description)');
+
+        if (!$description) {
+            $description = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/dc10:description)');
+        }
+
+        if (!$description) {
+            $description = null;
+        }
+
+        $this->data['description'] = $description;
+
+        return $this->data['description'];
+    }
+
+    /**
+     * Get the entry ID
+     *
+     * @return string
+     */
+    public function getId()
+    {
+        if (array_key_exists('id', $this->data)) {
+            return $this->data['id'];
+        }
+
+        $id = null;
+        $id = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/dc11:identifier)');
+
+        if (!$id) {
+            $id = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/dc10:identifier)');
+        }
+
+        $this->data['id'] = $id;
+
+        return $this->data['id'];
+    }
+
+    /**
+     * Get the entry title
+     *
+     * @return string
+     */
+    public function getTitle()
+    {
+        if (array_key_exists('title', $this->data)) {
+            return $this->data['title'];
+        }
+
+        $title = null;
+        $title = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/dc11:title)');
+
+        if (!$title) {
+            $title = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/dc10:title)');
+        }
+
+        if (!$title) {
+            $title = null;
+        }
+
+        $this->data['title'] = $title;
+
+        return $this->data['title'];
+    }
+
+    /**
+     *
+     *
+     * @return DateTime|null
+     */
+    public function getDate()
+    {
+        if (array_key_exists('date', $this->data)) {
+            return $this->data['date'];
+        }
+
+        $d    = null;
+        $date = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/dc11:date)');
+
+        if (!$date) {
+            $date = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/dc10:date)');
+        }
+
+        if ($date) {
+            $d = new DateTime($date);
+        }
+
+        $this->data['date'] = $d;
+
+        return $this->data['date'];
+    }
+
+    /**
+     * Register DC namespaces
+     *
+     * @return void
+     */
+    protected function registerNamespaces()
+    {
+        $this->getXpath()->registerNamespace('dc10', 'http://purl.org/dc/elements/1.0/');
+        $this->getXpath()->registerNamespace('dc11', 'http://purl.org/dc/elements/1.1/');
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/DublinCore/Feed.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/DublinCore/Feed.php
new file mode 100644
index 000000000000..61959c4a06d8
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/DublinCore/Feed.php
@@ -0,0 +1,281 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Extension\DublinCore;
+
+use DateTime;
+use Zend\Feed\Reader;
+use Zend\Feed\Reader\Collection;
+use Zend\Feed\Reader\Extension;
+
+class Feed extends Extension\AbstractFeed
+{
+    /**
+     * Get a single author
+     *
+     * @param  int $index
+     * @return string|null
+     */
+    public function getAuthor($index = 0)
+    {
+        $authors = $this->getAuthors();
+
+        if (isset($authors[$index])) {
+            return $authors[$index];
+        }
+
+        return null;
+    }
+
+    /**
+     * Get an array with feed authors
+     *
+     * @return array
+     */
+    public function getAuthors()
+    {
+        if (array_key_exists('authors', $this->data)) {
+            return $this->data['authors'];
+        }
+
+        $authors = array();
+        $list    = $this->getXpath()->query('//dc11:creator');
+
+        if (!$list->length) {
+            $list = $this->getXpath()->query('//dc10:creator');
+        }
+        if (!$list->length) {
+            $list = $this->getXpath()->query('//dc11:publisher');
+
+            if (!$list->length) {
+                $list = $this->getXpath()->query('//dc10:publisher');
+            }
+        }
+
+        if ($list->length) {
+            foreach ($list as $author) {
+                $authors[] = array(
+                    'name' => $author->nodeValue
+                );
+            }
+            $authors = new Collection\Author(
+                Reader\Reader::arrayUnique($authors)
+            );
+        } else {
+            $authors = null;
+        }
+
+        $this->data['authors'] = $authors;
+
+        return $this->data['authors'];
+    }
+
+    /**
+     * Get the copyright entry
+     *
+     * @return string|null
+     */
+    public function getCopyright()
+    {
+        if (array_key_exists('copyright', $this->data)) {
+            return $this->data['copyright'];
+        }
+
+        $copyright = null;
+        $copyright = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/dc11:rights)');
+
+        if (!$copyright) {
+            $copyright = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/dc10:rights)');
+        }
+
+        if (!$copyright) {
+            $copyright = null;
+        }
+
+        $this->data['copyright'] = $copyright;
+
+        return $this->data['copyright'];
+    }
+
+    /**
+     * Get the feed description
+     *
+     * @return string|null
+     */
+    public function getDescription()
+    {
+        if (array_key_exists('description', $this->data)) {
+            return $this->data['description'];
+        }
+
+        $description = null;
+        $description = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/dc11:description)');
+
+        if (!$description) {
+            $description = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/dc10:description)');
+        }
+
+        if (!$description) {
+            $description = null;
+        }
+
+        $this->data['description'] = $description;
+
+        return $this->data['description'];
+    }
+
+    /**
+     * Get the feed ID
+     *
+     * @return string|null
+     */
+    public function getId()
+    {
+        if (array_key_exists('id', $this->data)) {
+            return $this->data['id'];
+        }
+
+        $id = null;
+        $id = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/dc11:identifier)');
+
+        if (!$id) {
+            $id = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/dc10:identifier)');
+        }
+
+        $this->data['id'] = $id;
+
+        return $this->data['id'];
+    }
+
+    /**
+     * Get the feed language
+     *
+     * @return string|null
+     */
+    public function getLanguage()
+    {
+        if (array_key_exists('language', $this->data)) {
+            return $this->data['language'];
+        }
+
+        $language = null;
+        $language = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/dc11:language)');
+
+        if (!$language) {
+            $language = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/dc10:language)');
+        }
+
+        if (!$language) {
+            $language = null;
+        }
+
+        $this->data['language'] = $language;
+
+        return $this->data['language'];
+    }
+
+    /**
+     * Get the feed title
+     *
+     * @return string|null
+     */
+    public function getTitle()
+    {
+        if (array_key_exists('title', $this->data)) {
+            return $this->data['title'];
+        }
+
+        $title = null;
+        $title = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/dc11:title)');
+
+        if (!$title) {
+            $title = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/dc10:title)');
+        }
+
+        if (!$title) {
+            $title = null;
+        }
+
+        $this->data['title'] = $title;
+
+        return $this->data['title'];
+    }
+
+    /**
+     *
+     *
+     * @return DateTime|null
+     */
+    public function getDate()
+    {
+        if (array_key_exists('date', $this->data)) {
+            return $this->data['date'];
+        }
+
+        $d = null;
+        $date = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/dc11:date)');
+
+        if (!$date) {
+            $date = $this->getXpath()->evaluate('string(' . $this->getXpathPrefix() . '/dc10:date)');
+        }
+
+        if ($date) {
+            $d = new DateTime($date);
+        }
+
+        $this->data['date'] = $d;
+
+        return $this->data['date'];
+    }
+
+    /**
+     * Get categories (subjects under DC)
+     *
+     * @return Collection\Category
+     */
+    public function getCategories()
+    {
+        if (array_key_exists('categories', $this->data)) {
+            return $this->data['categories'];
+        }
+
+        $list = $this->getXpath()->evaluate($this->getXpathPrefix() . '//dc11:subject');
+
+        if (!$list->length) {
+            $list = $this->getXpath()->evaluate($this->getXpathPrefix() . '//dc10:subject');
+        }
+
+        if ($list->length) {
+            $categoryCollection = new Collection\Category;
+            foreach ($list as $category) {
+                $categoryCollection[] = array(
+                    'term' => $category->nodeValue,
+                    'scheme' => null,
+                    'label' => $category->nodeValue,
+                );
+            }
+        } else {
+            $categoryCollection = new Collection\Category;
+        }
+
+        $this->data['categories'] = $categoryCollection;
+        return $this->data['categories'];
+    }
+
+    /**
+     * Register the default namespaces for the current feed format
+     *
+     * @return void
+     */
+    protected function registerNamespaces()
+    {
+        $this->getXpath()->registerNamespace('dc10', 'http://purl.org/dc/elements/1.0/');
+        $this->getXpath()->registerNamespace('dc11', 'http://purl.org/dc/elements/1.1/');
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Podcast/Entry.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Podcast/Entry.php
new file mode 100644
index 000000000000..584fd375d2c9
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Podcast/Entry.php
@@ -0,0 +1,180 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Extension\Podcast;
+
+use Zend\Feed\Reader\Extension;
+
+/**
+*/
+class Entry extends Extension\AbstractEntry
+{
+    /**
+     * Get the entry author
+     *
+     * @return string
+     */
+    public function getCastAuthor()
+    {
+        if (isset($this->data['author'])) {
+            return $this->data['author'];
+        }
+
+        $author = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:author)');
+
+        if (!$author) {
+            $author = null;
+        }
+
+        $this->data['author'] = $author;
+
+        return $this->data['author'];
+    }
+
+    /**
+     * Get the entry block
+     *
+     * @return string
+     */
+    public function getBlock()
+    {
+        if (isset($this->data['block'])) {
+            return $this->data['block'];
+        }
+
+        $block = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:block)');
+
+        if (!$block) {
+            $block = null;
+        }
+
+        $this->data['block'] = $block;
+
+        return $this->data['block'];
+    }
+
+    /**
+     * Get the entry duration
+     *
+     * @return string
+     */
+    public function getDuration()
+    {
+        if (isset($this->data['duration'])) {
+            return $this->data['duration'];
+        }
+
+        $duration = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:duration)');
+
+        if (!$duration) {
+            $duration = null;
+        }
+
+        $this->data['duration'] = $duration;
+
+        return $this->data['duration'];
+    }
+
+    /**
+     * Get the entry explicit
+     *
+     * @return string
+     */
+    public function getExplicit()
+    {
+        if (isset($this->data['explicit'])) {
+            return $this->data['explicit'];
+        }
+
+        $explicit = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:explicit)');
+
+        if (!$explicit) {
+            $explicit = null;
+        }
+
+        $this->data['explicit'] = $explicit;
+
+        return $this->data['explicit'];
+    }
+
+    /**
+     * Get the entry keywords
+     *
+     * @return string
+     */
+    public function getKeywords()
+    {
+        if (isset($this->data['keywords'])) {
+            return $this->data['keywords'];
+        }
+
+        $keywords = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:keywords)');
+
+        if (!$keywords) {
+            $keywords = null;
+        }
+
+        $this->data['keywords'] = $keywords;
+
+        return $this->data['keywords'];
+    }
+
+    /**
+     * Get the entry subtitle
+     *
+     * @return string
+     */
+    public function getSubtitle()
+    {
+        if (isset($this->data['subtitle'])) {
+            return $this->data['subtitle'];
+        }
+
+        $subtitle = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:subtitle)');
+
+        if (!$subtitle) {
+            $subtitle = null;
+        }
+
+        $this->data['subtitle'] = $subtitle;
+
+        return $this->data['subtitle'];
+    }
+
+    /**
+     * Get the entry summary
+     *
+     * @return string
+     */
+    public function getSummary()
+    {
+        if (isset($this->data['summary'])) {
+            return $this->data['summary'];
+        }
+
+        $summary = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:summary)');
+
+        if (!$summary) {
+            $summary = null;
+        }
+
+        $this->data['summary'] = $summary;
+
+        return $this->data['summary'];
+    }
+
+    /**
+     * Register iTunes namespace
+     *
+     */
+    protected function registerNamespaces()
+    {
+        $this->xpath->registerNamespace('itunes', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Podcast/Feed.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Podcast/Feed.php
new file mode 100644
index 000000000000..b80bec9c31c2
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Podcast/Feed.php
@@ -0,0 +1,277 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Extension\Podcast;
+
+use DOMText;
+use Zend\Feed\Reader\Extension;
+
+/**
+*/
+class Feed extends Extension\AbstractFeed
+{
+    /**
+     * Get the entry author
+     *
+     * @return string
+     */
+    public function getCastAuthor()
+    {
+        if (isset($this->data['author'])) {
+            return $this->data['author'];
+        }
+
+        $author = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:author)');
+
+        if (!$author) {
+            $author = null;
+        }
+
+        $this->data['author'] = $author;
+
+        return $this->data['author'];
+    }
+
+    /**
+     * Get the entry block
+     *
+     * @return string
+     */
+    public function getBlock()
+    {
+        if (isset($this->data['block'])) {
+            return $this->data['block'];
+        }
+
+        $block = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:block)');
+
+        if (!$block) {
+            $block = null;
+        }
+
+        $this->data['block'] = $block;
+
+        return $this->data['block'];
+    }
+
+    /**
+     * Get the entry category
+     *
+     * @return string
+     */
+    public function getItunesCategories()
+    {
+        if (isset($this->data['categories'])) {
+            return $this->data['categories'];
+        }
+
+        $categoryList = $this->xpath->query($this->getXpathPrefix() . '/itunes:category');
+
+        $categories = array();
+
+        if ($categoryList->length > 0) {
+            foreach ($categoryList as $node) {
+                $children = null;
+
+                if ($node->childNodes->length > 0) {
+                    $children = array();
+
+                    foreach ($node->childNodes as $childNode) {
+                        if (!($childNode instanceof DOMText)) {
+                            $children[$childNode->getAttribute('text')] = null;
+                        }
+                    }
+                }
+
+                $categories[$node->getAttribute('text')] = $children;
+            }
+        }
+
+
+        if (!$categories) {
+            $categories = null;
+        }
+
+        $this->data['categories'] = $categories;
+
+        return $this->data['categories'];
+    }
+
+    /**
+     * Get the entry explicit
+     *
+     * @return string
+     */
+    public function getExplicit()
+    {
+        if (isset($this->data['explicit'])) {
+            return $this->data['explicit'];
+        }
+
+        $explicit = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:explicit)');
+
+        if (!$explicit) {
+            $explicit = null;
+        }
+
+        $this->data['explicit'] = $explicit;
+
+        return $this->data['explicit'];
+    }
+
+    /**
+     * Get the entry image
+     *
+     * @return string
+     */
+    public function getItunesImage()
+    {
+        if (isset($this->data['image'])) {
+            return $this->data['image'];
+        }
+
+        $image = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:image/@href)');
+
+        if (!$image) {
+            $image = null;
+        }
+
+        $this->data['image'] = $image;
+
+        return $this->data['image'];
+    }
+
+    /**
+     * Get the entry keywords
+     *
+     * @return string
+     */
+    public function getKeywords()
+    {
+        if (isset($this->data['keywords'])) {
+            return $this->data['keywords'];
+        }
+
+        $keywords = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:keywords)');
+
+        if (!$keywords) {
+            $keywords = null;
+        }
+
+        $this->data['keywords'] = $keywords;
+
+        return $this->data['keywords'];
+    }
+
+    /**
+     * Get the entry's new feed url
+     *
+     * @return string
+     */
+    public function getNewFeedUrl()
+    {
+        if (isset($this->data['new-feed-url'])) {
+            return $this->data['new-feed-url'];
+        }
+
+        $newFeedUrl = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:new-feed-url)');
+
+        if (!$newFeedUrl) {
+            $newFeedUrl = null;
+        }
+
+        $this->data['new-feed-url'] = $newFeedUrl;
+
+        return $this->data['new-feed-url'];
+    }
+
+    /**
+     * Get the entry owner
+     *
+     * @return string
+     */
+    public function getOwner()
+    {
+        if (isset($this->data['owner'])) {
+            return $this->data['owner'];
+        }
+
+        $owner = null;
+
+        $email = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:owner/itunes:email)');
+        $name  = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:owner/itunes:name)');
+
+        if (!empty($email)) {
+            $owner = $email . (empty($name) ? '' : ' (' . $name . ')');
+        } elseif (!empty($name)) {
+            $owner = $name;
+        }
+
+        if (!$owner) {
+            $owner = null;
+        }
+
+        $this->data['owner'] = $owner;
+
+        return $this->data['owner'];
+    }
+
+    /**
+     * Get the entry subtitle
+     *
+     * @return string
+     */
+    public function getSubtitle()
+    {
+        if (isset($this->data['subtitle'])) {
+            return $this->data['subtitle'];
+        }
+
+        $subtitle = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:subtitle)');
+
+        if (!$subtitle) {
+            $subtitle = null;
+        }
+
+        $this->data['subtitle'] = $subtitle;
+
+        return $this->data['subtitle'];
+    }
+
+    /**
+     * Get the entry summary
+     *
+     * @return string
+     */
+    public function getSummary()
+    {
+        if (isset($this->data['summary'])) {
+            return $this->data['summary'];
+        }
+
+        $summary = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:summary)');
+
+        if (!$summary) {
+            $summary = null;
+        }
+
+        $this->data['summary'] = $summary;
+
+        return $this->data['summary'];
+    }
+
+    /**
+     * Register iTunes namespace
+     *
+     */
+    protected function registerNamespaces()
+    {
+        $this->xpath->registerNamespace('itunes', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Slash/Entry.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Slash/Entry.php
new file mode 100644
index 000000000000..abd7eda905af
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Slash/Entry.php
@@ -0,0 +1,121 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Extension\Slash;
+
+use Zend\Feed\Reader\Extension;
+
+/**
+*/
+class Entry extends Extension\AbstractEntry
+{
+    /**
+     * Get the entry section
+     *
+     * @return string|null
+     */
+    public function getSection()
+    {
+        return $this->getData('section');
+    }
+
+    /**
+     * Get the entry department
+     *
+     * @return string|null
+     */
+    public function getDepartment()
+    {
+        return $this->getData('department');
+    }
+
+    /**
+     * Get the entry hit_parade
+     *
+     * @return array
+     */
+    public function getHitParade()
+    {
+        $name = 'hit_parade';
+
+        if (isset($this->data[$name])) {
+            return $this->data[$name];
+        }
+
+        $stringParade = $this->getData($name);
+        $hitParade    = array();
+
+        if (!empty($stringParade)) {
+            $stringParade = explode(',', $stringParade);
+
+            foreach ($stringParade as $hit)
+                $hitParade[] = $hit + 0; //cast to integer
+        }
+
+        $this->data[$name] = $hitParade;
+        return $hitParade;
+    }
+
+    /**
+     * Get the entry comments
+     *
+     * @return int
+     */
+    public function getCommentCount()
+    {
+        $name = 'comments';
+
+        if (isset($this->data[$name])) {
+            return $this->data[$name];
+        }
+
+        $comments = $this->getData($name, 'string');
+
+        if (!$comments) {
+            $this->data[$name] = null;
+            return $this->data[$name];
+        }
+
+        return $comments;
+    }
+
+    /**
+     * Get the entry data specified by name
+     * @param string $name
+     * @param string $type
+     *
+     * @return mixed|null
+     */
+    protected function getData($name, $type = 'string')
+    {
+        if (array_key_exists($name, $this->data)) {
+            return $this->data[$name];
+        }
+
+        $data = $this->xpath->evaluate($type . '(' . $this->getXpathPrefix() . '/slash10:' . $name . ')');
+
+        if (!$data) {
+            $data = null;
+        }
+
+        $this->data[$name] = $data;
+
+        return $data;
+    }
+
+    /**
+     * Register Slash namespaces
+     *
+     * @return void
+     */
+    protected function registerNamespaces()
+    {
+        $this->xpath->registerNamespace('slash10', 'http://purl.org/rss/1.0/modules/slash/');
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Syndication/Feed.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Syndication/Feed.php
new file mode 100644
index 000000000000..75f031b2899a
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Syndication/Feed.php
@@ -0,0 +1,149 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Extension\Syndication;
+
+use DateTime;
+use Zend\Feed\Reader;
+use Zend\Feed\Reader\Extension;
+
+class Feed extends \Zend\Feed\Reader\Extension\AbstractFeed
+{
+    /**
+     * Get update period
+     *
+     * @return string
+     * @throws Reader\Exception\InvalidArgumentException
+     */
+    public function getUpdatePeriod()
+    {
+        $name = 'updatePeriod';
+        $period = $this->_getData($name);
+
+        if ($period === null) {
+            $this->data[$name] = 'daily';
+            return 'daily'; //Default specified by spec
+        }
+
+        switch ($period) {
+            case 'hourly':
+            case 'daily':
+            case 'weekly':
+            case 'yearly':
+                return $period;
+            default:
+                throw new Reader\Exception\InvalidArgumentException("Feed specified invalid update period: '$period'."
+                    .  " Must be one of hourly, daily, weekly or yearly"
+                );
+        }
+    }
+
+    /**
+     * Get update frequency
+     * @return int
+     */
+    public function getUpdateFrequency()
+    {
+        $name = 'updateFrequency';
+        $freq = $this->_getData($name, 'number');
+
+        if (!$freq || $freq < 1) {
+            $this->data[$name] = 1;
+            return 1;
+        }
+
+        return $freq;
+    }
+
+    /**
+     * Get update frequency as ticks
+     * @return int
+     */
+    public function getUpdateFrequencyAsTicks()
+    {
+        $name = 'updateFrequency';
+        $freq = $this->_getData($name, 'number');
+
+        if (!$freq || $freq < 1) {
+            $this->data[$name] = 1;
+            $freq = 1;
+        }
+
+        $period = $this->getUpdatePeriod();
+        $ticks = 1;
+
+        switch ($period) {
+            case 'yearly':
+                $ticks *= 52; //TODO: fix generalisation, how?
+                // no break
+            case 'weekly':
+                $ticks *= 7;
+                // no break
+            case 'daily':
+                $ticks *= 24;
+                // no break
+            case 'hourly':
+                $ticks *= 3600;
+                break;
+            default: //Never arrive here, exception thrown in getPeriod()
+                break;
+        }
+
+        return $ticks / $freq;
+    }
+
+    /**
+     * Get update base
+     *
+     * @return DateTime|null
+     */
+    public function getUpdateBase()
+    {
+        $updateBase = $this->_getData('updateBase');
+        $date = null;
+        if ($updateBase) {
+            $date = DateTime::createFromFormat(DateTime::W3C, $updateBase);
+        }
+        return $date;
+    }
+
+    /**
+     * Get the entry data specified by name
+     *
+     * @param string $name
+     * @param string $type
+     * @return mixed|null
+     */
+    private function _getData($name, $type = 'string')
+    {
+        if (array_key_exists($name, $this->data)) {
+            return $this->data[$name];
+        }
+
+        $data = $this->xpath->evaluate($type . '(' . $this->getXpathPrefix() . '/syn10:' . $name . ')');
+
+        if (!$data) {
+            $data = null;
+        }
+
+        $this->data[$name] = $data;
+
+        return $data;
+    }
+
+    /**
+     * Register Syndication namespaces
+     *
+     * @return void
+     */
+    protected function registerNamespaces()
+    {
+        $this->xpath->registerNamespace('syn10', 'http://purl.org/rss/1.0/modules/syndication/');
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Thread/Entry.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Thread/Entry.php
new file mode 100644
index 000000000000..ceaee85bd573
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/Thread/Entry.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Extension\Thread;
+
+use Zend\Feed\Reader\Extension;
+
+/**
+*/
+class Entry extends Extension\AbstractEntry
+{
+    /**
+     * Get the "in-reply-to" value
+     *
+     * @return string
+     */
+    public function getInReplyTo()
+    {
+        // TODO: to be implemented
+    }
+
+    // TODO: Implement "replies" and "updated" constructs from standard
+
+    /**
+     * Get the total number of threaded responses (i.e comments)
+     *
+     * @return int|null
+     */
+    public function getCommentCount()
+    {
+        return $this->getData('total');
+    }
+
+    /**
+     * Get the entry data specified by name
+     *
+     * @param  string $name
+     * @return mixed|null
+     */
+    protected function getData($name)
+    {
+        if (array_key_exists($name, $this->data)) {
+            return $this->data[$name];
+        }
+
+        $data = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/thread10:' . $name . ')');
+
+        if (!$data) {
+            $data = null;
+        }
+
+        $this->data[$name] = $data;
+
+        return $data;
+    }
+
+    /**
+     * Register Atom Thread Extension 1.0 namespace
+     *
+     * @return void
+     */
+    protected function registerNamespaces()
+    {
+        $this->xpath->registerNamespace('thread10', 'http://purl.org/syndication/thread/1.0');
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/WellFormedWeb/Entry.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/WellFormedWeb/Entry.php
new file mode 100644
index 000000000000..cc52bc9088cf
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Extension/WellFormedWeb/Entry.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Extension\WellFormedWeb;
+
+use Zend\Feed\Reader\Extension;
+
+/**
+*/
+class Entry extends Extension\AbstractEntry
+{
+    /**
+     * Get the entry comment Uri
+     *
+     * @return string|null
+     */
+    public function getCommentFeedLink()
+    {
+        $name = 'commentRss';
+        if (array_key_exists($name, $this->data)) {
+            return $this->data[$name];
+        }
+
+        $data = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/wfw:' . $name . ')');
+
+        if (!$data) {
+            $data = null;
+        }
+
+        $this->data[$name] = $data;
+
+        return $data;
+    }
+
+    /**
+     * Register Slash namespaces
+     *
+     * @return void
+     */
+    protected function registerNamespaces()
+    {
+        $this->xpath->registerNamespace('wfw', 'http://wellformedweb.org/CommentAPI/');
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/ExtensionManager.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/ExtensionManager.php
new file mode 100644
index 000000000000..b6fa68db5109
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/ExtensionManager.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader;
+
+/**
+ * Default implementation of ExtensionManagerInterface
+ *
+ * Decorator of ExtensionPluginManager.
+ */
+class ExtensionManager implements ExtensionManagerInterface
+{
+    protected $pluginManager;
+
+    /**
+     * Constructor
+     *
+     * Seeds the extension manager with a plugin manager; if none provided,
+     * creates an instance.
+     *
+     * @param  null|ExtensionPluginManager $pluginManager
+     */
+    public function __construct(ExtensionPluginManager $pluginManager = null)
+    {
+        if (null === $pluginManager) {
+            $pluginManager = new ExtensionPluginManager();
+        }
+        $this->pluginManager = $pluginManager;
+    }
+
+    /**
+     * Method overloading
+     *
+     * Proxy to composed ExtensionPluginManager instance.
+     *
+     * @param  string $method
+     * @param  array $args
+     * @return mixed
+     * @throws Exception\BadMethodCallException
+     */
+    public function __call($method, $args)
+    {
+        if (!method_exists($this->pluginManager, $method)) {
+            throw new Exception\BadMethodCallException(sprintf(
+                'Method by name of %s does not exist in %s',
+                $method,
+                __CLASS__
+            ));
+        }
+        return call_user_func_array(array($this->pluginManager, $method), $args);
+    }
+
+    /**
+     * Get the named extension
+     *
+     * @param  string $name
+     * @return Extension\AbstractEntry|Extension\AbstractFeed
+     */
+    public function get($name)
+    {
+        return $this->pluginManager->get($name);
+    }
+
+    /**
+     * Do we have the named extension?
+     *
+     * @param  string $name
+     * @return bool
+     */
+    public function has($name)
+    {
+        return $this->pluginManager->has($name);
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/ExtensionManagerInterface.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/ExtensionManagerInterface.php
new file mode 100644
index 000000000000..6ae9b6798e1f
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/ExtensionManagerInterface.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader;
+
+interface ExtensionManagerInterface
+{
+    /**
+     * Do we have the extension?
+     *
+     * @param  string $extension
+     * @return bool
+     */
+    public function has($extension);
+
+    /**
+     * Retrieve the extension
+     *
+     * @param  string $extension
+     * @return mixed
+     */
+    public function get($extension);
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/ExtensionPluginManager.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/ExtensionPluginManager.php
new file mode 100644
index 000000000000..8222ee2c1c6c
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/ExtensionPluginManager.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader;
+
+use Zend\ServiceManager\AbstractPluginManager;
+
+/**
+ * Plugin manager implementation for feed reader extensions based on the
+ * AbstractPluginManager.
+ *
+ * Validation checks that we have an Extension\AbstractEntry or
+ * Extension\AbstractFeed.
+ */
+class ExtensionPluginManager extends AbstractPluginManager
+{
+    /**
+     * Default set of extension classes
+     *
+     * @var array
+     */
+    protected $invokableClasses = array(
+        'atomentry'            => 'Zend\Feed\Reader\Extension\Atom\Entry',
+        'atomfeed'             => 'Zend\Feed\Reader\Extension\Atom\Feed',
+        'contententry'         => 'Zend\Feed\Reader\Extension\Content\Entry',
+        'creativecommonsentry' => 'Zend\Feed\Reader\Extension\CreativeCommons\Entry',
+        'creativecommonsfeed'  => 'Zend\Feed\Reader\Extension\CreativeCommons\Feed',
+        'dublincoreentry'      => 'Zend\Feed\Reader\Extension\DublinCore\Entry',
+        'dublincorefeed'       => 'Zend\Feed\Reader\Extension\DublinCore\Feed',
+        'podcastentry'         => 'Zend\Feed\Reader\Extension\Podcast\Entry',
+        'podcastfeed'          => 'Zend\Feed\Reader\Extension\Podcast\Feed',
+        'slashentry'           => 'Zend\Feed\Reader\Extension\Slash\Entry',
+        'syndicationfeed'      => 'Zend\Feed\Reader\Extension\Syndication\Feed',
+        'threadentry'          => 'Zend\Feed\Reader\Extension\Thread\Entry',
+        'wellformedwebentry'   => 'Zend\Feed\Reader\Extension\WellFormedWeb\Entry',
+    );
+
+    /**
+     * Do not share instances
+     *
+     * @var bool
+     */
+    protected $shareByDefault = false;
+
+    /**
+     * Validate the plugin
+     *
+     * Checks that the extension loaded is of a valid type.
+     *
+     * @param  mixed $plugin
+     * @return void
+     * @throws Exception\InvalidArgumentException if invalid
+     */
+    public function validatePlugin($plugin)
+    {
+        if ($plugin instanceof Extension\AbstractEntry
+            || $plugin instanceof Extension\AbstractFeed
+        ) {
+            // we're okay
+            return;
+        }
+
+        throw new Exception\InvalidArgumentException(sprintf(
+            'Plugin of type %s is invalid; must implement %s\Extension\AbstractFeed '
+            . 'or %s\Extension\AbstractEntry',
+            (is_object($plugin) ? get_class($plugin) : gettype($plugin)),
+            __NAMESPACE__,
+            __NAMESPACE__
+        ));
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Feed/AbstractFeed.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Feed/AbstractFeed.php
new file mode 100644
index 000000000000..643818405c27
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Feed/AbstractFeed.php
@@ -0,0 +1,307 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Feed;
+
+use DOMDocument;
+use DOMElement;
+use DOMXPath;
+use Zend\Feed\Reader;
+use Zend\Feed\Reader\Exception;
+
+/**
+*/
+abstract class AbstractFeed implements FeedInterface
+{
+    /**
+     * Parsed feed data
+     *
+     * @var array
+     */
+    protected $data = array();
+
+    /**
+     * Parsed feed data in the shape of a DOMDocument
+     *
+     * @var DOMDocument
+     */
+    protected $domDocument = null;
+
+    /**
+     * An array of parsed feed entries
+     *
+     * @var array
+     */
+    protected $entries = array();
+
+    /**
+     * A pointer for the iterator to keep track of the entries array
+     *
+     * @var int
+     */
+    protected $entriesKey = 0;
+
+    /**
+     * The base XPath query used to retrieve feed data
+     *
+     * @var DOMXPath
+     */
+    protected $xpath = null;
+
+    /**
+     * Array of loaded extensions
+     *
+     * @var array
+     */
+    protected $extensions = array();
+
+    /**
+     * Original Source URI (set if imported from a URI)
+     *
+     * @var string
+     */
+    protected $originalSourceUri = null;
+
+    /**
+     * Constructor
+     *
+     * @param DOMDocument $domDocument The DOM object for the feed's XML
+     * @param string $type Feed type
+     */
+    public function __construct(DOMDocument $domDocument, $type = null)
+    {
+        $this->domDocument = $domDocument;
+        $this->xpath = new DOMXPath($this->domDocument);
+
+        if ($type !== null) {
+            $this->data['type'] = $type;
+        } else {
+            $this->data['type'] = Reader\Reader::detectType($this->domDocument);
+        }
+        $this->registerNamespaces();
+        $this->indexEntries();
+        $this->loadExtensions();
+    }
+
+    /**
+     * Set an original source URI for the feed being parsed. This value
+     * is returned from getFeedLink() method if the feed does not carry
+     * a self-referencing URI.
+     *
+     * @param string $uri
+     */
+    public function setOriginalSourceUri($uri)
+    {
+        $this->originalSourceUri = $uri;
+    }
+
+    /**
+     * Get an original source URI for the feed being parsed. Returns null if
+     * unset or the feed was not imported from a URI.
+     *
+     * @return string|null
+     */
+    public function getOriginalSourceUri()
+    {
+        return $this->originalSourceUri;
+    }
+
+    /**
+     * Get the number of feed entries.
+     * Required by the Iterator interface.
+     *
+     * @return int
+     */
+    public function count()
+    {
+        return count($this->entries);
+    }
+
+    /**
+     * Return the current entry
+     *
+     * @return \Zend\Feed\Reader\Entry\EntryInterface
+     */
+    public function current()
+    {
+        if (substr($this->getType(), 0, 3) == 'rss') {
+            $reader = new Reader\Entry\Rss($this->entries[$this->key()], $this->key(), $this->getType());
+        } else {
+            $reader = new Reader\Entry\Atom($this->entries[$this->key()], $this->key(), $this->getType());
+        }
+
+        $reader->setXpath($this->xpath);
+
+        return $reader;
+    }
+
+    /**
+     * Get the DOM
+     *
+     * @return DOMDocument
+     */
+    public function getDomDocument()
+    {
+        return $this->domDocument;
+    }
+
+    /**
+     * Get the Feed's encoding
+     *
+     * @return string
+     */
+    public function getEncoding()
+    {
+        $assumed = $this->getDomDocument()->encoding;
+        if (empty($assumed)) {
+            $assumed = 'UTF-8';
+        }
+        return $assumed;
+    }
+
+    /**
+     * Get feed as xml
+     *
+     * @return string
+     */
+    public function saveXml()
+    {
+          return $this->getDomDocument()->saveXml();
+    }
+
+    /**
+     * Get the DOMElement representing the items/feed element
+     *
+     * @return DOMElement
+     */
+    public function getElement()
+    {
+          return $this->getDomDocument()->documentElement;
+    }
+
+    /**
+     * Get the DOMXPath object for this feed
+     *
+     * @return DOMXPath
+     */
+    public function getXpath()
+    {
+          return $this->xpath;
+    }
+
+    /**
+     * Get the feed type
+     *
+     * @return string
+     */
+    public function getType()
+    {
+        return $this->data['type'];
+    }
+
+    /**
+     * Return the current feed key
+     *
+     * @return int
+     */
+    public function key()
+    {
+        return $this->entriesKey;
+    }
+
+    /**
+     * Move the feed pointer forward
+     *
+     */
+    public function next()
+    {
+        ++$this->entriesKey;
+    }
+
+    /**
+     * Reset the pointer in the feed object
+     *
+     */
+    public function rewind()
+    {
+        $this->entriesKey = 0;
+    }
+
+    /**
+     * Check to see if the iterator is still valid
+     *
+     * @return bool
+     */
+    public function valid()
+    {
+        return 0 <= $this->entriesKey && $this->entriesKey < $this->count();
+    }
+
+    public function getExtensions()
+    {
+        return $this->extensions;
+    }
+
+    public function __call($method, $args)
+    {
+        foreach ($this->extensions as $extension) {
+            if (method_exists($extension, $method)) {
+                return call_user_func_array(array($extension, $method), $args);
+            }
+        }
+        throw new Exception\BadMethodCallException('Method: ' . $method
+        . 'does not exist and could not be located on a registered Extension');
+    }
+
+    /**
+     * Return an Extension object with the matching name (postfixed with _Feed)
+     *
+     * @param string $name
+     * @return \Zend\Feed\Reader\Extension\AbstractFeed
+     */
+    public function getExtension($name)
+    {
+        if (array_key_exists($name . '\\Feed', $this->extensions)) {
+            return $this->extensions[$name . '\\Feed'];
+        }
+        return null;
+    }
+
+    protected function loadExtensions()
+    {
+        $all     = Reader\Reader::getExtensions();
+        $manager = Reader\Reader::getExtensionManager();
+        $feed    = $all['feed'];
+        foreach ($feed as $extension) {
+            if (in_array($extension, $all['core'])) {
+                continue;
+            }
+            if (!$manager->has($extension)) {
+                throw new Exception\RuntimeException(sprintf('Unable to load extension "%s"; cannot find class', $extension));
+            }
+            $plugin = $manager->get($extension);
+            $plugin->setDomDocument($this->getDomDocument());
+            $plugin->setType($this->data['type']);
+            $plugin->setXpath($this->xpath);
+            $this->extensions[$extension] = $plugin;
+        }
+    }
+
+    /**
+     * Read all entries to the internal entries array
+     *
+     */
+    abstract protected function indexEntries();
+
+    /**
+     * Register the default namespaces for the current feed format
+     *
+     */
+    abstract protected function registerNamespaces();
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Feed/Atom.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Feed/Atom.php
new file mode 100644
index 000000000000..cc3943854111
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Feed/Atom.php
@@ -0,0 +1,410 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Feed;
+
+use DOMDocument;
+use Zend\Feed\Reader;
+
+/**
+*/
+class Atom extends AbstractFeed
+{
+
+    /**
+     * Constructor
+     *
+     * @param  DOMDocument $dom
+     * @param  string $type
+     */
+    public function __construct(DOMDocument $dom, $type = null)
+    {
+        parent::__construct($dom, $type);
+        $manager = Reader\Reader::getExtensionManager();
+
+        $atomFeed = $manager->get('Atom\Feed');
+        $atomFeed->setDomDocument($dom);
+        $atomFeed->setType($this->data['type']);
+        $atomFeed->setXpath($this->xpath);
+        $this->extensions['Atom\\Feed'] = $atomFeed;
+
+        $atomFeed = $manager->get('DublinCore\Feed');
+        $atomFeed->setDomDocument($dom);
+        $atomFeed->setType($this->data['type']);
+        $atomFeed->setXpath($this->xpath);
+        $this->extensions['DublinCore\\Feed'] = $atomFeed;
+
+        foreach ($this->extensions as $extension) {
+            $extension->setXpathPrefix('/atom:feed');
+        }
+    }
+
+    /**
+     * Get a single author
+     *
+     * @param  int $index
+     * @return string|null
+     */
+    public function getAuthor($index = 0)
+    {
+        $authors = $this->getAuthors();
+
+        if (isset($authors[$index])) {
+            return $authors[$index];
+        }
+
+        return null;
+    }
+
+    /**
+     * Get an array with feed authors
+     *
+     * @return array
+     */
+    public function getAuthors()
+    {
+        if (array_key_exists('authors', $this->data)) {
+            return $this->data['authors'];
+        }
+
+        $authors = $this->getExtension('Atom')->getAuthors();
+
+        $this->data['authors'] = $authors;
+
+        return $this->data['authors'];
+    }
+
+    /**
+     * Get the copyright entry
+     *
+     * @return string|null
+     */
+    public function getCopyright()
+    {
+        if (array_key_exists('copyright', $this->data)) {
+            return $this->data['copyright'];
+        }
+
+        $copyright = $this->getExtension('Atom')->getCopyright();
+
+        if (!$copyright) {
+            $copyright = null;
+        }
+
+        $this->data['copyright'] = $copyright;
+
+        return $this->data['copyright'];
+    }
+
+    /**
+     * Get the feed creation date
+     *
+     * @return string|null
+     */
+    public function getDateCreated()
+    {
+        if (array_key_exists('datecreated', $this->data)) {
+            return $this->data['datecreated'];
+        }
+
+        $dateCreated = $this->getExtension('Atom')->getDateCreated();
+
+        if (!$dateCreated) {
+            $dateCreated = null;
+        }
+
+        $this->data['datecreated'] = $dateCreated;
+
+        return $this->data['datecreated'];
+    }
+
+    /**
+     * Get the feed modification date
+     *
+     * @return string|null
+     */
+    public function getDateModified()
+    {
+        if (array_key_exists('datemodified', $this->data)) {
+            return $this->data['datemodified'];
+        }
+
+        $dateModified = $this->getExtension('Atom')->getDateModified();
+
+        if (!$dateModified) {
+            $dateModified = null;
+        }
+
+        $this->data['datemodified'] = $dateModified;
+
+        return $this->data['datemodified'];
+    }
+
+    /**
+     * Get the feed lastBuild date. This is not implemented in Atom.
+     *
+     * @return string|null
+     */
+    public function getLastBuildDate()
+    {
+        return null;
+    }
+
+    /**
+     * Get the feed description
+     *
+     * @return string|null
+     */
+    public function getDescription()
+    {
+        if (array_key_exists('description', $this->data)) {
+            return $this->data['description'];
+        }
+
+        $description = $this->getExtension('Atom')->getDescription();
+
+        if (!$description) {
+            $description = null;
+        }
+
+        $this->data['description'] = $description;
+
+        return $this->data['description'];
+    }
+
+    /**
+     * Get the feed generator entry
+     *
+     * @return string|null
+     */
+    public function getGenerator()
+    {
+        if (array_key_exists('generator', $this->data)) {
+            return $this->data['generator'];
+        }
+
+        $generator = $this->getExtension('Atom')->getGenerator();
+
+        $this->data['generator'] = $generator;
+
+        return $this->data['generator'];
+    }
+
+    /**
+     * Get the feed ID
+     *
+     * @return string|null
+     */
+    public function getId()
+    {
+        if (array_key_exists('id', $this->data)) {
+            return $this->data['id'];
+        }
+
+        $id = $this->getExtension('Atom')->getId();
+
+        $this->data['id'] = $id;
+
+        return $this->data['id'];
+    }
+
+    /**
+     * Get the feed language
+     *
+     * @return string|null
+     */
+    public function getLanguage()
+    {
+        if (array_key_exists('language', $this->data)) {
+            return $this->data['language'];
+        }
+
+        $language = $this->getExtension('Atom')->getLanguage();
+
+        if (!$language) {
+            $language = $this->xpath->evaluate('string(//@xml:lang[1])');
+        }
+
+        if (!$language) {
+            $language = null;
+        }
+
+        $this->data['language'] = $language;
+
+        return $this->data['language'];
+    }
+
+    /**
+     * Get a link to the source website
+     *
+     * @return string|null
+     */
+    public function getBaseUrl()
+    {
+        if (array_key_exists('baseUrl', $this->data)) {
+            return $this->data['baseUrl'];
+        }
+
+        $baseUrl = $this->getExtension('Atom')->getBaseUrl();
+
+        $this->data['baseUrl'] = $baseUrl;
+
+        return $this->data['baseUrl'];
+    }
+
+    /**
+     * Get a link to the source website
+     *
+     * @return string|null
+     */
+    public function getLink()
+    {
+        if (array_key_exists('link', $this->data)) {
+            return $this->data['link'];
+        }
+
+        $link = $this->getExtension('Atom')->getLink();
+
+        $this->data['link'] = $link;
+
+        return $this->data['link'];
+    }
+
+    /**
+     * Get feed image data
+     *
+     * @return array|null
+     */
+    public function getImage()
+    {
+        if (array_key_exists('image', $this->data)) {
+            return $this->data['image'];
+        }
+
+        $link = $this->getExtension('Atom')->getImage();
+
+        $this->data['image'] = $link;
+
+        return $this->data['image'];
+    }
+
+    /**
+     * Get a link to the feed's XML Url
+     *
+     * @return string|null
+     */
+    public function getFeedLink()
+    {
+        if (array_key_exists('feedlink', $this->data)) {
+            return $this->data['feedlink'];
+        }
+
+        $link = $this->getExtension('Atom')->getFeedLink();
+
+        if ($link === null || empty($link)) {
+            $link = $this->getOriginalSourceUri();
+        }
+
+        $this->data['feedlink'] = $link;
+
+        return $this->data['feedlink'];
+    }
+
+    /**
+     * Get the feed title
+     *
+     * @return string|null
+     */
+    public function getTitle()
+    {
+        if (array_key_exists('title', $this->data)) {
+            return $this->data['title'];
+        }
+
+        $title = $this->getExtension('Atom')->getTitle();
+
+        $this->data['title'] = $title;
+
+        return $this->data['title'];
+    }
+
+    /**
+     * Get an array of any supported Pusubhubbub endpoints
+     *
+     * @return array|null
+     */
+    public function getHubs()
+    {
+        if (array_key_exists('hubs', $this->data)) {
+            return $this->data['hubs'];
+        }
+
+        $hubs = $this->getExtension('Atom')->getHubs();
+
+        $this->data['hubs'] = $hubs;
+
+        return $this->data['hubs'];
+    }
+
+    /**
+     * Get all categories
+     *
+     * @return Reader\Collection\Category
+     */
+    public function getCategories()
+    {
+        if (array_key_exists('categories', $this->data)) {
+            return $this->data['categories'];
+        }
+
+        $categoryCollection = $this->getExtension('Atom')->getCategories();
+
+        if (count($categoryCollection) == 0) {
+            $categoryCollection = $this->getExtension('DublinCore')->getCategories();
+        }
+
+        $this->data['categories'] = $categoryCollection;
+
+        return $this->data['categories'];
+    }
+
+    /**
+     * Read all entries to the internal entries array
+     *
+     * @return void
+     */
+    protected function indexEntries()
+    {
+        if ($this->getType() == Reader\Reader::TYPE_ATOM_10 ||
+            $this->getType() == Reader\Reader::TYPE_ATOM_03) {
+            $entries = array();
+            $entries = $this->xpath->evaluate('//atom:entry');
+
+            foreach ($entries as $index => $entry) {
+                $this->entries[$index] = $entry;
+            }
+        }
+    }
+
+    /**
+     * Register the default namespaces for the current feed format
+     *
+     */
+    protected function registerNamespaces()
+    {
+        switch ($this->data['type']) {
+            case Reader\Reader::TYPE_ATOM_03:
+                $this->xpath->registerNamespace('atom', Reader\Reader::NAMESPACE_ATOM_03);
+                break;
+            case Reader\Reader::TYPE_ATOM_10:
+            default:
+                $this->xpath->registerNamespace('atom', Reader\Reader::NAMESPACE_ATOM_10);
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Feed/Atom/Source.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Feed/Atom/Source.php
new file mode 100644
index 000000000000..3055dc3215f7
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Feed/Atom/Source.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Feed\Atom;
+
+use DOMElement;
+use DOMXPath;
+use Zend\Feed\Reader;
+use Zend\Feed\Reader\Feed;
+
+/**
+*/
+class Source extends Feed\Atom
+{
+
+    /**
+     * Constructor: Create a Source object which is largely just a normal
+     * Zend\Feed\Reader\AbstractFeed object only designed to retrieve feed level
+     * metadata from an Atom entry's source element.
+     *
+     * @param DOMElement $source
+     * @param string $xpathPrefix Passed from parent Entry object
+     * @param string $type Nearly always Atom 1.0
+     */
+    public function __construct(DOMElement $source, $xpathPrefix, $type = Reader\Reader::TYPE_ATOM_10)
+    {
+        $this->domDocument = $source->ownerDocument;
+        $this->xpath = new DOMXPath($this->domDocument);
+        $this->data['type'] = $type;
+        $this->registerNamespaces();
+        $this->loadExtensions();
+
+        $manager = Reader\Reader::getExtensionManager();
+        $extensions = array('Atom\Feed', 'DublinCore\Feed');
+
+        foreach ($extensions as $name) {
+            $extension = $manager->get($name);
+            $extension->setDomDocument($this->domDocument);
+            $extension->setType($this->data['type']);
+            $extension->setXpath($this->xpath);
+            $this->extensions[$name] = $extension;
+        }
+
+        foreach ($this->extensions as $extension) {
+            $extension->setXpathPrefix(rtrim($xpathPrefix, '/') . '/atom:source');
+        }
+    }
+
+    /**
+     * Since this is not an Entry carrier but a vehicle for Feed metadata, any
+     * applicable Entry methods are stubbed out and do nothing.
+     */
+
+    /**
+     * @return void
+     */
+    public function count() {}
+
+    /**
+     * @return void
+     */
+    public function current() {}
+
+    /**
+     * @return void
+     */
+    public function key() {}
+
+    /**
+     * @return void
+     */
+    public function next() {}
+
+    /**
+     * @return void
+     */
+    public function rewind() {}
+
+    /**
+     * @return void
+     */
+    public function valid() {}
+
+    /**
+     * @return void
+     */
+    protected function indexEntries() {}
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Feed/FeedInterface.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Feed/FeedInterface.php
new file mode 100644
index 000000000000..c66bb7bff272
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Feed/FeedInterface.php
@@ -0,0 +1,111 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Feed;
+
+use Countable;
+use Iterator;
+
+/**
+*/
+interface FeedInterface extends Iterator, Countable
+{
+    /**
+     * Get a single author
+     *
+     * @param  int $index
+     * @return string|null
+     */
+    public function getAuthor($index = 0);
+
+    /**
+     * Get an array with feed authors
+     *
+     * @return array
+     */
+    public function getAuthors();
+
+    /**
+     * Get the copyright entry
+     *
+     * @return string|null
+     */
+    public function getCopyright();
+
+    /**
+     * Get the feed creation date
+     *
+     * @return string|null
+     */
+    public function getDateCreated();
+
+    /**
+     * Get the feed modification date
+     *
+     * @return string|null
+     */
+    public function getDateModified();
+
+    /**
+     * Get the feed description
+     *
+     * @return string|null
+     */
+    public function getDescription();
+
+    /**
+     * Get the feed generator entry
+     *
+     * @return string|null
+     */
+    public function getGenerator();
+
+    /**
+     * Get the feed ID
+     *
+     * @return string|null
+     */
+    public function getId();
+
+    /**
+     * Get the feed language
+     *
+     * @return string|null
+     */
+    public function getLanguage();
+
+    /**
+     * Get a link to the HTML source
+     *
+     * @return string|null
+     */
+    public function getLink();
+
+    /**
+     * Get a link to the XML feed
+     *
+     * @return string|null
+     */
+    public function getFeedLink();
+
+    /**
+     * Get the feed title
+     *
+     * @return string|null
+     */
+    public function getTitle();
+
+    /**
+     * Get all categories
+     *
+     * @return \Zend\Feed\Reader\Collection\Category
+     */
+    public function getCategories();
+
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Feed/Rss.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Feed/Rss.php
new file mode 100644
index 000000000000..61ce229ba442
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Feed/Rss.php
@@ -0,0 +1,709 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Feed;
+
+use DateTime;
+use DOMDocument;
+use Zend\Feed\Reader;
+use Zend\Feed\Reader\Collection;
+use Zend\Feed\Reader\Exception;
+
+/**
+*/
+class Rss extends AbstractFeed
+{
+
+    /**
+     * Constructor
+     *
+     * @param  DOMDocument $dom
+     * @param  string $type
+     */
+    public function __construct(DOMDocument $dom, $type = null)
+    {
+        parent::__construct($dom, $type);
+
+        $manager = Reader\Reader::getExtensionManager();
+
+        $feed = $manager->get('DublinCore\Feed');
+        $feed->setDomDocument($dom);
+        $feed->setType($this->data['type']);
+        $feed->setXpath($this->xpath);
+        $this->extensions['DublinCore\Feed'] = $feed;
+
+        $feed = $manager->get('Atom\Feed');
+        $feed->setDomDocument($dom);
+        $feed->setType($this->data['type']);
+        $feed->setXpath($this->xpath);
+        $this->extensions['Atom\Feed'] = $feed;
+
+        if ($this->getType() !== Reader\Reader::TYPE_RSS_10
+            && $this->getType() !== Reader\Reader::TYPE_RSS_090
+        ) {
+            $xpathPrefix = '/rss/channel';
+        } else {
+            $xpathPrefix = '/rdf:RDF/rss:channel';
+        }
+        foreach ($this->extensions as $extension) {
+            $extension->setXpathPrefix($xpathPrefix);
+        }
+    }
+
+    /**
+     * Get a single author
+     *
+     * @param  int $index
+     * @return string|null
+     */
+    public function getAuthor($index = 0)
+    {
+        $authors = $this->getAuthors();
+
+        if (isset($authors[$index])) {
+            return $authors[$index];
+        }
+
+        return null;
+    }
+
+    /**
+     * Get an array with feed authors
+     *
+     * @return array
+     */
+    public function getAuthors()
+    {
+        if (array_key_exists('authors', $this->data)) {
+            return $this->data['authors'];
+        }
+
+        $authors = array();
+        $authorsDc = $this->getExtension('DublinCore')->getAuthors();
+        if (!empty($authorsDc)) {
+            foreach ($authorsDc as $author) {
+                $authors[] = array(
+                    'name' => $author['name']
+                );
+            }
+        }
+
+        /**
+         * Technically RSS doesn't specific author element use at the feed level
+         * but it's supported on a "just in case" basis.
+         */
+        if ($this->getType() !== Reader\Reader::TYPE_RSS_10
+        && $this->getType() !== Reader\Reader::TYPE_RSS_090) {
+            $list = $this->xpath->query('//author');
+        } else {
+            $list = $this->xpath->query('//rss:author');
+        }
+        if ($list->length) {
+            foreach ($list as $author) {
+                $string = trim($author->nodeValue);
+                $email = null;
+                $name = null;
+                $data = array();
+                // Pretty rough parsing - but it's a catchall
+                if (preg_match("/^.*@[^ ]*/", $string, $matches)) {
+                    $data['email'] = trim($matches[0]);
+                    if (preg_match("/\((.*)\)$/", $string, $matches)) {
+                        $data['name'] = $matches[1];
+                    }
+                    $authors[] = $data;
+                }
+            }
+        }
+
+        if (count($authors) == 0) {
+            $authors = $this->getExtension('Atom')->getAuthors();
+        } else {
+            $authors = new Reader\Collection\Author(
+                Reader\Reader::arrayUnique($authors)
+            );
+        }
+
+        if (count($authors) == 0) {
+            $authors = null;
+        }
+
+        $this->data['authors'] = $authors;
+
+        return $this->data['authors'];
+    }
+
+    /**
+     * Get the copyright entry
+     *
+     * @return string|null
+     */
+    public function getCopyright()
+    {
+        if (array_key_exists('copyright', $this->data)) {
+            return $this->data['copyright'];
+        }
+
+        $copyright = null;
+
+        if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
+            $this->getType() !== Reader\Reader::TYPE_RSS_090) {
+            $copyright = $this->xpath->evaluate('string(/rss/channel/copyright)');
+        }
+
+        if (!$copyright && $this->getExtension('DublinCore') !== null) {
+            $copyright = $this->getExtension('DublinCore')->getCopyright();
+        }
+
+        if (empty($copyright)) {
+            $copyright = $this->getExtension('Atom')->getCopyright();
+        }
+
+        if (!$copyright) {
+            $copyright = null;
+        }
+
+        $this->data['copyright'] = $copyright;
+
+        return $this->data['copyright'];
+    }
+
+    /**
+     * Get the feed creation date
+     *
+     * @return string|null
+     */
+    public function getDateCreated()
+    {
+        return $this->getDateModified();
+    }
+
+    /**
+     * Get the feed modification date
+     *
+     * @return DateTime
+     * @throws Exception\RuntimeException
+     */
+    public function getDateModified()
+    {
+        if (array_key_exists('datemodified', $this->data)) {
+            return $this->data['datemodified'];
+        }
+
+        $dateModified = null;
+        $date = null;
+
+        if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
+            $this->getType() !== Reader\Reader::TYPE_RSS_090) {
+            $dateModified = $this->xpath->evaluate('string(/rss/channel/pubDate)');
+            if (!$dateModified) {
+                $dateModified = $this->xpath->evaluate('string(/rss/channel/lastBuildDate)');
+            }
+            if ($dateModified) {
+                $dateModifiedParsed = strtotime($dateModified);
+                if ($dateModifiedParsed) {
+                    $date = new DateTime('@' . $dateModifiedParsed);
+                } else {
+                    $dateStandards = array(DateTime::RSS, DateTime::RFC822,
+                                           DateTime::RFC2822, null);
+                    foreach ($dateStandards as $standard) {
+                        try {
+                            $date = DateTime::createFromFormat($standard, $dateModified);
+                            break;
+                        } catch (\Exception $e) {
+                            if ($standard == null) {
+                                throw new Exception\RuntimeException(
+                                    'Could not load date due to unrecognised'
+                                    .' format (should follow RFC 822 or 2822):'
+                                    . $e->getMessage(),
+                                    0, $e
+                                );
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        if (!$date) {
+            $date = $this->getExtension('DublinCore')->getDate();
+        }
+
+        if (!$date) {
+            $date = $this->getExtension('Atom')->getDateModified();
+        }
+
+        if (!$date) {
+            $date = null;
+        }
+
+        $this->data['datemodified'] = $date;
+
+        return $this->data['datemodified'];
+    }
+
+    /**
+     * Get the feed lastBuild date
+     *
+     * @throws Exception\RuntimeException
+     * @return DateTime
+     */
+    public function getLastBuildDate()
+    {
+        if (array_key_exists('lastBuildDate', $this->data)) {
+            return $this->data['lastBuildDate'];
+        }
+
+        $lastBuildDate = null;
+        $date = null;
+
+        if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
+            $this->getType() !== Reader\Reader::TYPE_RSS_090) {
+            $lastBuildDate = $this->xpath->evaluate('string(/rss/channel/lastBuildDate)');
+            if ($lastBuildDate) {
+                $lastBuildDateParsed = strtotime($lastBuildDate);
+                if ($lastBuildDateParsed) {
+                    $date = new DateTime('@' . $lastBuildDateParsed);
+                } else {
+                    $dateStandards = array(DateTime::RSS, DateTime::RFC822,
+                                           DateTime::RFC2822, null);
+                    foreach ($dateStandards as $standard) {
+                        try {
+                            $date = DateTime::createFromFormat($standard, $lastBuildDateParsed);
+                            break;
+                        } catch (\Exception $e) {
+                            if ($standard == null) {
+                                throw new Exception\RuntimeException(
+                                    'Could not load date due to unrecognised'
+                                    .' format (should follow RFC 822 or 2822):'
+                                    . $e->getMessage(),
+                                    0, $e
+                                );
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        if (!$date) {
+            $date = null;
+        }
+
+        $this->data['lastBuildDate'] = $date;
+
+        return $this->data['lastBuildDate'];
+    }
+
+    /**
+     * Get the feed description
+     *
+     * @return string|null
+     */
+    public function getDescription()
+    {
+        if (array_key_exists('description', $this->data)) {
+            return $this->data['description'];
+        }
+
+        $description = null;
+
+        if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
+            $this->getType() !== Reader\Reader::TYPE_RSS_090) {
+            $description = $this->xpath->evaluate('string(/rss/channel/description)');
+        } else {
+            $description = $this->xpath->evaluate('string(/rdf:RDF/rss:channel/rss:description)');
+        }
+
+        if (!$description && $this->getExtension('DublinCore') !== null) {
+            $description = $this->getExtension('DublinCore')->getDescription();
+        }
+
+        if (empty($description)) {
+            $description = $this->getExtension('Atom')->getDescription();
+        }
+
+        if (!$description) {
+            $description = null;
+        }
+
+        $this->data['description'] = $description;
+
+        return $this->data['description'];
+    }
+
+    /**
+     * Get the feed ID
+     *
+     * @return string|null
+     */
+    public function getId()
+    {
+        if (array_key_exists('id', $this->data)) {
+            return $this->data['id'];
+        }
+
+        $id = null;
+
+        if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
+            $this->getType() !== Reader\Reader::TYPE_RSS_090) {
+            $id = $this->xpath->evaluate('string(/rss/channel/guid)');
+        }
+
+        if (!$id && $this->getExtension('DublinCore') !== null) {
+            $id = $this->getExtension('DublinCore')->getId();
+        }
+
+        if (empty($id)) {
+            $id = $this->getExtension('Atom')->getId();
+        }
+
+        if (!$id) {
+            if ($this->getLink()) {
+                $id = $this->getLink();
+            } elseif ($this->getTitle()) {
+                $id = $this->getTitle();
+            } else {
+                $id = null;
+            }
+        }
+
+        $this->data['id'] = $id;
+
+        return $this->data['id'];
+    }
+
+    /**
+     * Get the feed image data
+     *
+     * @return array|null
+     */
+    public function getImage()
+    {
+        if (array_key_exists('image', $this->data)) {
+            return $this->data['image'];
+        }
+
+        if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
+            $this->getType() !== Reader\Reader::TYPE_RSS_090) {
+            $list = $this->xpath->query('/rss/channel/image');
+            $prefix = '/rss/channel/image[1]';
+        } else {
+            $list = $this->xpath->query('/rdf:RDF/rss:channel/rss:image');
+            $prefix = '/rdf:RDF/rss:channel/rss:image[1]';
+        }
+        if ($list->length > 0) {
+            $image = array();
+            $value = $this->xpath->evaluate('string(' . $prefix . '/url)');
+            if ($value) {
+                $image['uri'] = $value;
+            }
+            $value = $this->xpath->evaluate('string(' . $prefix . '/link)');
+            if ($value) {
+                $image['link'] = $value;
+            }
+            $value = $this->xpath->evaluate('string(' . $prefix . '/title)');
+            if ($value) {
+                $image['title'] = $value;
+            }
+            $value = $this->xpath->evaluate('string(' . $prefix . '/height)');
+            if ($value) {
+                $image['height'] = $value;
+            }
+            $value = $this->xpath->evaluate('string(' . $prefix . '/width)');
+            if ($value) {
+                $image['width'] = $value;
+            }
+            $value = $this->xpath->evaluate('string(' . $prefix . '/description)');
+            if ($value) {
+                $image['description'] = $value;
+            }
+        } else {
+            $image = null;
+        }
+
+        $this->data['image'] = $image;
+
+        return $this->data['image'];
+    }
+
+    /**
+     * Get the feed language
+     *
+     * @return string|null
+     */
+    public function getLanguage()
+    {
+        if (array_key_exists('language', $this->data)) {
+            return $this->data['language'];
+        }
+
+        $language = null;
+
+        if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
+            $this->getType() !== Reader\Reader::TYPE_RSS_090) {
+            $language = $this->xpath->evaluate('string(/rss/channel/language)');
+        }
+
+        if (!$language && $this->getExtension('DublinCore') !== null) {
+            $language = $this->getExtension('DublinCore')->getLanguage();
+        }
+
+        if (empty($language)) {
+            $language = $this->getExtension('Atom')->getLanguage();
+        }
+
+        if (!$language) {
+            $language = $this->xpath->evaluate('string(//@xml:lang[1])');
+        }
+
+        if (!$language) {
+            $language = null;
+        }
+
+        $this->data['language'] = $language;
+
+        return $this->data['language'];
+    }
+
+    /**
+     * Get a link to the feed
+     *
+     * @return string|null
+     */
+    public function getLink()
+    {
+        if (array_key_exists('link', $this->data)) {
+            return $this->data['link'];
+        }
+
+        $link = null;
+
+        if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
+            $this->getType() !== Reader\Reader::TYPE_RSS_090) {
+            $link = $this->xpath->evaluate('string(/rss/channel/link)');
+        } else {
+            $link = $this->xpath->evaluate('string(/rdf:RDF/rss:channel/rss:link)');
+        }
+
+        if (empty($link)) {
+            $link = $this->getExtension('Atom')->getLink();
+        }
+
+        if (!$link) {
+            $link = null;
+        }
+
+        $this->data['link'] = $link;
+
+        return $this->data['link'];
+    }
+
+    /**
+     * Get a link to the feed XML
+     *
+     * @return string|null
+     */
+    public function getFeedLink()
+    {
+        if (array_key_exists('feedlink', $this->data)) {
+            return $this->data['feedlink'];
+        }
+
+        $link = null;
+
+        $link = $this->getExtension('Atom')->getFeedLink();
+
+        if ($link === null || empty($link)) {
+            $link = $this->getOriginalSourceUri();
+        }
+
+        $this->data['feedlink'] = $link;
+
+        return $this->data['feedlink'];
+    }
+
+    /**
+     * Get the feed generator entry
+     *
+     * @return string|null
+     */
+    public function getGenerator()
+    {
+        if (array_key_exists('generator', $this->data)) {
+            return $this->data['generator'];
+        }
+
+        $generator = null;
+
+        if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
+            $this->getType() !== Reader\Reader::TYPE_RSS_090) {
+            $generator = $this->xpath->evaluate('string(/rss/channel/generator)');
+        }
+
+        if (!$generator) {
+            if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
+            $this->getType() !== Reader\Reader::TYPE_RSS_090) {
+                $generator = $this->xpath->evaluate('string(/rss/channel/atom:generator)');
+            } else {
+                $generator = $this->xpath->evaluate('string(/rdf:RDF/rss:channel/atom:generator)');
+            }
+        }
+
+        if (empty($generator)) {
+            $generator = $this->getExtension('Atom')->getGenerator();
+        }
+
+        if (!$generator) {
+            $generator = null;
+        }
+
+        $this->data['generator'] = $generator;
+
+        return $this->data['generator'];
+    }
+
+    /**
+     * Get the feed title
+     *
+     * @return string|null
+     */
+    public function getTitle()
+    {
+        if (array_key_exists('title', $this->data)) {
+            return $this->data['title'];
+        }
+
+        $title = null;
+
+        if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
+            $this->getType() !== Reader\Reader::TYPE_RSS_090) {
+            $title = $this->xpath->evaluate('string(/rss/channel/title)');
+        } else {
+            $title = $this->xpath->evaluate('string(/rdf:RDF/rss:channel/rss:title)');
+        }
+
+        if (!$title && $this->getExtension('DublinCore') !== null) {
+            $title = $this->getExtension('DublinCore')->getTitle();
+        }
+
+        if (!$title) {
+            $title = $this->getExtension('Atom')->getTitle();
+        }
+
+        if (!$title) {
+            $title = null;
+        }
+
+        $this->data['title'] = $title;
+
+        return $this->data['title'];
+    }
+
+    /**
+     * Get an array of any supported Pusubhubbub endpoints
+     *
+     * @return array|null
+     */
+    public function getHubs()
+    {
+        if (array_key_exists('hubs', $this->data)) {
+            return $this->data['hubs'];
+        }
+
+        $hubs = $this->getExtension('Atom')->getHubs();
+
+        if (empty($hubs)) {
+            $hubs = null;
+        } else {
+            $hubs = array_unique($hubs);
+        }
+
+        $this->data['hubs'] = $hubs;
+
+        return $this->data['hubs'];
+    }
+
+    /**
+     * Get all categories
+     *
+     * @return Reader\Collection\Category
+     */
+    public function getCategories()
+    {
+        if (array_key_exists('categories', $this->data)) {
+            return $this->data['categories'];
+        }
+
+        if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
+            $this->getType() !== Reader\Reader::TYPE_RSS_090) {
+            $list = $this->xpath->query('/rss/channel//category');
+        } else {
+            $list = $this->xpath->query('/rdf:RDF/rss:channel//rss:category');
+        }
+
+        if ($list->length) {
+            $categoryCollection = new Collection\Category;
+            foreach ($list as $category) {
+                $categoryCollection[] = array(
+                    'term' => $category->nodeValue,
+                    'scheme' => $category->getAttribute('domain'),
+                    'label' => $category->nodeValue,
+                );
+            }
+        } else {
+            $categoryCollection = $this->getExtension('DublinCore')->getCategories();
+        }
+
+        if (count($categoryCollection) == 0) {
+            $categoryCollection = $this->getExtension('Atom')->getCategories();
+        }
+
+        $this->data['categories'] = $categoryCollection;
+
+        return $this->data['categories'];
+    }
+
+    /**
+     * Read all entries to the internal entries array
+     *
+     */
+    protected function indexEntries()
+    {
+        $entries = array();
+
+        if ($this->getType() !== Reader\Reader::TYPE_RSS_10 && $this->getType() !== Reader\Reader::TYPE_RSS_090) {
+            $entries = $this->xpath->evaluate('//item');
+        } else {
+            $entries = $this->xpath->evaluate('//rss:item');
+        }
+
+        foreach ($entries as $index => $entry) {
+            $this->entries[$index] = $entry;
+        }
+    }
+
+    /**
+     * Register the default namespaces for the current feed format
+     *
+     */
+    protected function registerNamespaces()
+    {
+        switch ($this->data['type']) {
+            case Reader\Reader::TYPE_RSS_10:
+                $this->xpath->registerNamespace('rdf', Reader\Reader::NAMESPACE_RDF);
+                $this->xpath->registerNamespace('rss', Reader\Reader::NAMESPACE_RSS_10);
+                break;
+
+            case Reader\Reader::TYPE_RSS_090:
+                $this->xpath->registerNamespace('rdf', Reader\Reader::NAMESPACE_RDF);
+                $this->xpath->registerNamespace('rss', Reader\Reader::NAMESPACE_RSS_090);
+                break;
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/FeedSet.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/FeedSet.php
new file mode 100644
index 000000000000..c9476208d28c
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/FeedSet.php
@@ -0,0 +1,127 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader;
+
+use ArrayObject;
+use DOMNodeList;
+use Zend\Feed\Uri;
+
+/**
+*/
+class FeedSet extends ArrayObject
+{
+
+    public $rss = null;
+
+    public $rdf = null;
+
+    public $atom = null;
+
+    /**
+     * Import a DOMNodeList from any document containing a set of links
+     * for alternate versions of a document, which will normally refer to
+     * RSS/RDF/Atom feeds for the current document.
+     *
+     * All such links are stored internally, however the first instance of
+     * each RSS, RDF or Atom type has its URI stored as a public property
+     * as a shortcut where the use case is simply to get a quick feed ref.
+     *
+     * Note that feeds are not loaded at this point, but will be lazy
+     * loaded automatically when each links 'feed' array key is accessed.
+     *
+     * @param DOMNodeList $links
+     * @param string $uri
+     * @return void
+     */
+    public function addLinks(DOMNodeList $links, $uri)
+    {
+        foreach ($links as $link) {
+            if (strtolower($link->getAttribute('rel')) !== 'alternate'
+                || !$link->getAttribute('type') || !$link->getAttribute('href')) {
+                continue;
+            }
+            if (!isset($this->rss) && $link->getAttribute('type') == 'application/rss+xml') {
+                $this->rss = $this->absolutiseUri(trim($link->getAttribute('href')), $uri);
+            } elseif (!isset($this->atom) && $link->getAttribute('type') == 'application/atom+xml') {
+                $this->atom = $this->absolutiseUri(trim($link->getAttribute('href')), $uri);
+            } elseif (!isset($this->rdf) && $link->getAttribute('type') == 'application/rdf+xml') {
+                $this->rdf = $this->absolutiseUri(trim($link->getAttribute('href')), $uri);
+            }
+            $this[] = new static(array(
+                'rel' => 'alternate',
+                'type' => $link->getAttribute('type'),
+                'href' => $this->absolutiseUri(trim($link->getAttribute('href')), $uri),
+            ));
+        }
+    }
+
+    /**
+     *  Attempt to turn a relative URI into an absolute URI
+     */
+    protected function absolutiseUri($link, $uri = null)
+    {
+        $linkUri = Uri::factory($link);
+        if (!$linkUri->isAbsolute() or !$linkUri->isValid()) {
+            if ($uri !== null) {
+                $uri = Uri::factory($uri);
+
+                if ($link[0] !== '/') {
+                    $link = $uri->getPath() . '/' . $link;
+                }
+
+                $link = $uri->getScheme() . '://' . $uri->getHost() . '/' . $this->canonicalizePath($link);
+                if (!Uri::factory($link)->isValid()) {
+                    $link = null;
+                }
+            }
+        }
+        return $link;
+    }
+
+    /**
+     *  Canonicalize relative path
+     */
+    protected function canonicalizePath($path)
+    {
+        $parts = array_filter(explode('/', $path));
+        $absolutes = array();
+        foreach ($parts as $part) {
+            if ('.' == $part) {
+                continue;
+            }
+            if ('..' == $part) {
+                array_pop($absolutes);
+            } else {
+                $absolutes[] = $part;
+            }
+        }
+        return implode('/', $absolutes);
+    }
+
+    /**
+     * Supports lazy loading of feeds using Reader::import() but
+     * delegates any other operations to the parent class.
+     *
+     * @param string $offset
+     * @return mixed
+     */
+    public function offsetGet($offset)
+    {
+        if ($offset == 'feed' && !$this->offsetExists('feed')) {
+            if (!$this->offsetExists('href')) {
+                return null;
+            }
+            $feed = Reader::import($this->offsetGet('href'));
+            $this->offsetSet('feed', $feed);
+            return $feed;
+        }
+        return parent::offsetGet($offset);
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Http/ClientInterface.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Http/ClientInterface.php
new file mode 100644
index 000000000000..dc0f5f694da2
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Http/ClientInterface.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Http;
+
+interface ClientInterface
+{
+    /**
+     * Make a GET request to a given URI
+     *
+     * @param  string $uri
+     * @return ResponseInterface
+     */
+    public function get($uri);
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Http/ResponseInterface.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Http/ResponseInterface.php
new file mode 100644
index 000000000000..5027f2005459
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Http/ResponseInterface.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader\Http;
+
+interface ResponseInterface
+{
+    /**
+     * Retrieve the response body
+     *
+     * @return string
+     */
+    public function getBody();
+
+    /**
+     * Retrieve the HTTP response status code
+     *
+     * @return int
+     */
+    public function getStatusCode();
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Reader.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Reader.php
new file mode 100644
index 000000000000..7f8a25c20d89
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Reader/Reader.php
@@ -0,0 +1,674 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Reader;
+
+use DOMDocument;
+use DOMXPath;
+use Zend\Cache\Storage\StorageInterface as CacheStorage;
+use Zend\Http as ZendHttp;
+use Zend\Stdlib\ErrorHandler;
+
+/**
+*/
+class Reader
+{
+    /**
+     * Namespace constants
+     */
+    const NAMESPACE_ATOM_03  = 'http://purl.org/atom/ns#';
+    const NAMESPACE_ATOM_10  = 'http://www.w3.org/2005/Atom';
+    const NAMESPACE_RDF      = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
+    const NAMESPACE_RSS_090  = 'http://my.netscape.com/rdf/simple/0.9/';
+    const NAMESPACE_RSS_10   = 'http://purl.org/rss/1.0/';
+
+    /**
+     * Feed type constants
+     */
+    const TYPE_ANY              = 'any';
+    const TYPE_ATOM_03          = 'atom-03';
+    const TYPE_ATOM_10          = 'atom-10';
+    const TYPE_ATOM_10_ENTRY    = 'atom-10-entry';
+    const TYPE_ATOM_ANY         = 'atom';
+    const TYPE_RSS_090          = 'rss-090';
+    const TYPE_RSS_091          = 'rss-091';
+    const TYPE_RSS_091_NETSCAPE = 'rss-091n';
+    const TYPE_RSS_091_USERLAND = 'rss-091u';
+    const TYPE_RSS_092          = 'rss-092';
+    const TYPE_RSS_093          = 'rss-093';
+    const TYPE_RSS_094          = 'rss-094';
+    const TYPE_RSS_10           = 'rss-10';
+    const TYPE_RSS_20           = 'rss-20';
+    const TYPE_RSS_ANY          = 'rss';
+
+    /**
+     * Cache instance
+     *
+     * @var CacheStorage
+     */
+    protected static $cache = null;
+
+    /**
+     * HTTP client object to use for retrieving feeds
+     *
+     * @var ZendHttp\Client
+     */
+    protected static $httpClient = null;
+
+    /**
+     * Override HTTP PUT and DELETE request methods?
+     *
+     * @var bool
+     */
+    protected static $httpMethodOverride = false;
+
+    protected static $httpConditionalGet = false;
+
+    protected static $extensionManager = null;
+
+    protected static $extensions = array(
+        'feed' => array(
+            'DublinCore\Feed',
+            'Atom\Feed'
+        ),
+        'entry' => array(
+            'Content\Entry',
+            'DublinCore\Entry',
+            'Atom\Entry'
+        ),
+        'core' => array(
+            'DublinCore\Feed',
+            'Atom\Feed',
+            'Content\Entry',
+            'DublinCore\Entry',
+            'Atom\Entry'
+        )
+    );
+
+    /**
+     * Get the Feed cache
+     *
+     * @return CacheStorage
+     */
+    public static function getCache()
+    {
+        return static::$cache;
+    }
+
+    /**
+     * Set the feed cache
+     *
+     * @param  CacheStorage $cache
+     * @return void
+     */
+    public static function setCache(CacheStorage $cache)
+    {
+        static::$cache = $cache;
+    }
+
+    /**
+     * Set the HTTP client instance
+     *
+     * Sets the HTTP client object to use for retrieving the feeds.
+     *
+     * @param  ZendHttp\Client $httpClient
+     * @return void
+     */
+    public static function setHttpClient(ZendHttp\Client $httpClient)
+    {
+        static::$httpClient = $httpClient;
+    }
+
+
+    /**
+     * Gets the HTTP client object. If none is set, a new ZendHttp\Client will be used.
+     *
+     * @return ZendHttp\Client
+     */
+    public static function getHttpClient()
+    {
+        if (!static::$httpClient instanceof ZendHttp\Client) {
+            static::$httpClient = new ZendHttp\Client();
+        }
+
+        return static::$httpClient;
+    }
+
+    /**
+     * Toggle using POST instead of PUT and DELETE HTTP methods
+     *
+     * Some feed implementations do not accept PUT and DELETE HTTP
+     * methods, or they can't be used because of proxies or other
+     * measures. This allows turning on using POST where PUT and
+     * DELETE would normally be used; in addition, an
+     * X-Method-Override header will be sent with a value of PUT or
+     * DELETE as appropriate.
+     *
+     * @param  bool $override Whether to override PUT and DELETE.
+     * @return void
+     */
+    public static function setHttpMethodOverride($override = true)
+    {
+        static::$httpMethodOverride = $override;
+    }
+
+    /**
+     * Get the HTTP override state
+     *
+     * @return bool
+     */
+    public static function getHttpMethodOverride()
+    {
+        return static::$httpMethodOverride;
+    }
+
+    /**
+     * Set the flag indicating whether or not to use HTTP conditional GET
+     *
+     * @param  bool $bool
+     * @return void
+     */
+    public static function useHttpConditionalGet($bool = true)
+    {
+        static::$httpConditionalGet = $bool;
+    }
+
+    /**
+     * Import a feed by providing a URI
+     *
+     * @param  string $uri The URI to the feed
+     * @param  string $etag OPTIONAL Last received ETag for this resource
+     * @param  string $lastModified OPTIONAL Last-Modified value for this resource
+     * @return Feed\FeedInterface
+     * @throws Exception\RuntimeException
+     */
+    public static function import($uri, $etag = null, $lastModified = null)
+    {
+        $cache       = self::getCache();
+        $feed        = null;
+        $responseXml = '';
+        $client      = self::getHttpClient();
+        $client->resetParameters();
+        $headers = new ZendHttp\Headers();
+        $client->setHeaders($headers);
+        $client->setUri($uri);
+        $cacheId = 'Zend_Feed_Reader_' . md5($uri);
+
+        if (static::$httpConditionalGet && $cache) {
+            $data = $cache->getItem($cacheId);
+            if ($data) {
+                if ($etag === null) {
+                    $etag = $cache->getItem($cacheId . '_etag');
+                }
+                if ($lastModified === null) {
+                    $lastModified = $cache->getItem($cacheId . '_lastmodified');
+                }
+                if ($etag) {
+                    $headers->addHeaderLine('If-None-Match', $etag);
+                }
+                if ($lastModified) {
+                    $headers->addHeaderLine('If-Modified-Since', $lastModified);
+                }
+            }
+            $response = $client->send();
+            if ($response->getStatusCode() !== 200 && $response->getStatusCode() !== 304) {
+                throw new Exception\RuntimeException('Feed failed to load, got response code ' . $response->getStatusCode());
+            }
+            if ($response->getStatusCode() == 304) {
+                $responseXml = $data;
+            } else {
+                $responseXml = $response->getBody();
+                $cache->setItem($cacheId, $responseXml);
+                if ($response->getHeaders()->get('ETag')) {
+                    $cache->setItem($cacheId . '_etag', $response->getHeaders()->get('ETag')->getFieldValue());
+                }
+                if ($response->getHeaders()->get('Last-Modified')) {
+                    $cache->setItem($cacheId . '_lastmodified', $response->getHeaders()->get('Last-Modified')->getFieldValue());
+                }
+            }
+            return static::importString($responseXml);
+        } elseif ($cache) {
+            $data = $cache->getItem($cacheId);
+            if ($data) {
+                return static::importString($data);
+            }
+            $response = $client->send();
+            if ((int) $response->getStatusCode() !== 200) {
+                throw new Exception\RuntimeException('Feed failed to load, got response code ' . $response->getStatusCode());
+            }
+            $responseXml = $response->getBody();
+            $cache->setItem($cacheId, $responseXml);
+            return static::importString($responseXml);
+        } else {
+            $response = $client->send();
+            if ((int) $response->getStatusCode() !== 200) {
+                throw new Exception\RuntimeException('Feed failed to load, got response code ' . $response->getStatusCode());
+            }
+            $reader = static::importString($response->getBody());
+            $reader->setOriginalSourceUri($uri);
+            return $reader;
+        }
+    }
+
+    /**
+     * Import a feed from a remote URI
+     *
+     * Performs similarly to import(), except it uses the HTTP client passed to
+     * the method, and does not take into account cached data.
+     *
+     * Primary purpose is to make it possible to use the Reader with alternate
+     * HTTP client implementations.
+     *
+     * @param  string $uri
+     * @param  Http\Client $client
+     * @return self
+     * @throws Exception\RuntimeException if response is not an Http\ResponseInterface
+     */
+    public static function importRemoteFeed($uri, Http\ClientInterface $client)
+    {
+        $response = $client->get($uri);
+        if (!$response instanceof Http\ResponseInterface) {
+            throw new Exception\RuntimeException(sprintf(
+                'Did not receive a %s\Http\ResponseInterface from the provided HTTP client; received "%s"',
+                __NAMESPACE__,
+                (is_object($response) ? get_class($response) : gettype($response))
+            ));
+        }
+
+        if ((int) $response->getStatusCode() !== 200) {
+            throw new Exception\RuntimeException('Feed failed to load, got response code ' . $response->getStatusCode());
+        }
+        $reader = static::importString($response->getBody());
+        $reader->setOriginalSourceUri($uri);
+        return $reader;
+    }
+
+    /**
+     * Import a feed from a string
+     *
+     * @param  string $string
+     * @return Feed\FeedInterface
+     * @throws Exception\InvalidArgumentException
+     * @throws Exception\RuntimeException
+     */
+    public static function importString($string)
+    {
+        $libxmlErrflag = libxml_use_internal_errors(true);
+        $oldValue = libxml_disable_entity_loader(true);
+        $dom = new DOMDocument;
+        $status = $dom->loadXML(trim($string));
+        foreach ($dom->childNodes as $child) {
+            if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
+                throw new Exception\InvalidArgumentException(
+                    'Invalid XML: Detected use of illegal DOCTYPE'
+                );
+            }
+        }
+        libxml_disable_entity_loader($oldValue);
+        libxml_use_internal_errors($libxmlErrflag);
+
+        if (!$status) {
+            // Build error message
+            $error = libxml_get_last_error();
+            if ($error && $error->message) {
+                $error->message = trim($error->message);
+                $errormsg = "DOMDocument cannot parse XML: {$error->message}";
+            } else {
+                $errormsg = "DOMDocument cannot parse XML: Please check the XML document's validity";
+            }
+            throw new Exception\RuntimeException($errormsg);
+        }
+
+        $type = static::detectType($dom);
+
+        static::registerCoreExtensions();
+
+        if (substr($type, 0, 3) == 'rss') {
+            $reader = new Feed\Rss($dom, $type);
+        } elseif (substr($type, 8, 5) == 'entry') {
+            $reader = new Entry\Atom($dom->documentElement, 0, self::TYPE_ATOM_10);
+        } elseif (substr($type, 0, 4) == 'atom') {
+            $reader = new Feed\Atom($dom, $type);
+        } else {
+            throw new Exception\RuntimeException('The URI used does not point to a '
+            . 'valid Atom, RSS or RDF feed that Zend\Feed\Reader can parse.');
+        }
+        return $reader;
+    }
+
+    /**
+     * Imports a feed from a file located at $filename.
+     *
+     * @param  string $filename
+     * @throws Exception\RuntimeException
+     * @return Feed\FeedInterface
+     */
+    public static function importFile($filename)
+    {
+        ErrorHandler::start();
+        $feed = file_get_contents($filename);
+        $err  = ErrorHandler::stop();
+        if ($feed === false) {
+            throw new Exception\RuntimeException("File '{$filename}' could not be loaded", 0, $err);
+        }
+        return static::importString($feed);
+    }
+
+    /**
+     * Find feed links
+     *
+     * @param $uri
+     * @return FeedSet
+     * @throws Exception\RuntimeException
+     */
+    public static function findFeedLinks($uri)
+    {
+        $client = static::getHttpClient();
+        $client->setUri($uri);
+        $response = $client->send();
+        if ($response->getStatusCode() !== 200) {
+            throw new Exception\RuntimeException("Failed to access $uri, got response code " . $response->getStatusCode());
+        }
+        $responseHtml = $response->getBody();
+        $libxmlErrflag = libxml_use_internal_errors(true);
+        $oldValue = libxml_disable_entity_loader(true);
+        $dom = new DOMDocument;
+        $status = $dom->loadHTML(trim($responseHtml));
+        libxml_disable_entity_loader($oldValue);
+        libxml_use_internal_errors($libxmlErrflag);
+        if (!$status) {
+            // Build error message
+            $error = libxml_get_last_error();
+            if ($error && $error->message) {
+                $error->message = trim($error->message);
+                $errormsg = "DOMDocument cannot parse HTML: {$error->message}";
+            } else {
+                $errormsg = "DOMDocument cannot parse HTML: Please check the XML document's validity";
+            }
+            throw new Exception\RuntimeException($errormsg);
+        }
+        $feedSet = new FeedSet;
+        $links = $dom->getElementsByTagName('link');
+        $feedSet->addLinks($links, $uri);
+        return $feedSet;
+    }
+
+    /**
+     * Detect the feed type of the provided feed
+     *
+     * @param  Feed\AbstractFeed|DOMDocument|string $feed
+     * @param  bool $specOnly
+     * @return string
+     * @throws Exception\InvalidArgumentException
+     * @throws Exception\RuntimeException
+     */
+    public static function detectType($feed, $specOnly = false)
+    {
+        if ($feed instanceof Feed\AbstractFeed) {
+            $dom = $feed->getDomDocument();
+        } elseif ($feed instanceof DOMDocument) {
+            $dom = $feed;
+        } elseif (is_string($feed) && !empty($feed)) {
+            ErrorHandler::start(E_NOTICE|E_WARNING);
+            ini_set('track_errors', 1);
+            $oldValue = libxml_disable_entity_loader(true);
+            $dom = new DOMDocument;
+            $status = $dom->loadXML($feed);
+            foreach ($dom->childNodes as $child) {
+                if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
+                    throw new Exception\InvalidArgumentException(
+                        'Invalid XML: Detected use of illegal DOCTYPE'
+                    );
+                }
+            }
+            libxml_disable_entity_loader($oldValue);
+            ini_restore('track_errors');
+            ErrorHandler::stop();
+            if (!$status) {
+                if (!isset($phpErrormsg)) {
+                    if (function_exists('xdebug_is_enabled')) {
+                        $phpErrormsg = '(error message not available, when XDebug is running)';
+                    } else {
+                        $phpErrormsg = '(error message not available)';
+                    }
+                }
+                throw new Exception\RuntimeException("DOMDocument cannot parse XML: $phpErrormsg");
+            }
+        } else {
+            throw new Exception\InvalidArgumentException('Invalid object/scalar provided: must'
+            . ' be of type Zend\Feed\Reader\Feed, DomDocument or string');
+        }
+        $xpath = new DOMXPath($dom);
+
+        if ($xpath->query('/rss')->length) {
+            $type = self::TYPE_RSS_ANY;
+            $version = $xpath->evaluate('string(/rss/@version)');
+
+            if (strlen($version) > 0) {
+                switch ($version) {
+                    case '2.0':
+                        $type = self::TYPE_RSS_20;
+                        break;
+
+                    case '0.94':
+                        $type = self::TYPE_RSS_094;
+                        break;
+
+                    case '0.93':
+                        $type = self::TYPE_RSS_093;
+                        break;
+
+                    case '0.92':
+                        $type = self::TYPE_RSS_092;
+                        break;
+
+                    case '0.91':
+                        $type = self::TYPE_RSS_091;
+                        break;
+                }
+            }
+
+            return $type;
+        }
+
+        $xpath->registerNamespace('rdf', self::NAMESPACE_RDF);
+
+        if ($xpath->query('/rdf:RDF')->length) {
+            $xpath->registerNamespace('rss', self::NAMESPACE_RSS_10);
+
+            if ($xpath->query('/rdf:RDF/rss:channel')->length
+                || $xpath->query('/rdf:RDF/rss:image')->length
+                || $xpath->query('/rdf:RDF/rss:item')->length
+                || $xpath->query('/rdf:RDF/rss:textinput')->length
+            ) {
+                return self::TYPE_RSS_10;
+            }
+
+            $xpath->registerNamespace('rss', self::NAMESPACE_RSS_090);
+
+            if ($xpath->query('/rdf:RDF/rss:channel')->length
+                || $xpath->query('/rdf:RDF/rss:image')->length
+                || $xpath->query('/rdf:RDF/rss:item')->length
+                || $xpath->query('/rdf:RDF/rss:textinput')->length
+            ) {
+                return self::TYPE_RSS_090;
+            }
+        }
+
+        $xpath->registerNamespace('atom', self::NAMESPACE_ATOM_10);
+
+        if ($xpath->query('//atom:feed')->length) {
+            return self::TYPE_ATOM_10;
+        }
+
+        if ($xpath->query('//atom:entry')->length) {
+            if ($specOnly == true) {
+                return self::TYPE_ATOM_10;
+            } else {
+                return self::TYPE_ATOM_10_ENTRY;
+            }
+        }
+
+        $xpath->registerNamespace('atom', self::NAMESPACE_ATOM_03);
+
+        if ($xpath->query('//atom:feed')->length) {
+            return self::TYPE_ATOM_03;
+        }
+
+        return self::TYPE_ANY;
+    }
+
+    /**
+     * Set plugin manager for use with Extensions
+     *
+     * @param ExtensionManagerInterface $extensionManager
+     */
+    public static function setExtensionManager(ExtensionManagerInterface $extensionManager)
+    {
+        static::$extensionManager = $extensionManager;
+    }
+
+    /**
+     * Get plugin manager for use with Extensions
+     *
+     * @return ExtensionManagerInterface
+     */
+    public static function getExtensionManager()
+    {
+        if (!isset(static::$extensionManager)) {
+            static::setExtensionManager(new ExtensionManager());
+        }
+        return static::$extensionManager;
+    }
+
+    /**
+     * Register an Extension by name
+     *
+     * @param  string $name
+     * @return void
+     * @throws Exception\RuntimeException if unable to resolve Extension class
+     */
+    public static function registerExtension($name)
+    {
+        $feedName  = $name . '\Feed';
+        $entryName = $name . '\Entry';
+        $manager   = static::getExtensionManager();
+        if (static::isRegistered($name)) {
+            if ($manager->has($feedName) || $manager->has($entryName)) {
+                return;
+            }
+        }
+
+        if (!$manager->has($feedName) && !$manager->has($entryName)) {
+            throw new Exception\RuntimeException('Could not load extension: ' . $name
+                . ' using Plugin Loader. Check prefix paths are configured and extension exists.');
+        }
+        if ($manager->has($feedName)) {
+            static::$extensions['feed'][] = $feedName;
+        }
+        if ($manager->has($entryName)) {
+            static::$extensions['entry'][] = $entryName;
+        }
+    }
+
+    /**
+     * Is a given named Extension registered?
+     *
+     * @param  string $extensionName
+     * @return bool
+     */
+    public static function isRegistered($extensionName)
+    {
+        $feedName  = $extensionName . '\Feed';
+        $entryName = $extensionName . '\Entry';
+        if (in_array($feedName, static::$extensions['feed'])
+            || in_array($entryName, static::$extensions['entry'])
+        ) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Get a list of extensions
+     *
+     * @return array
+     */
+    public static function getExtensions()
+    {
+        return static::$extensions;
+    }
+
+    /**
+     * Reset class state to defaults
+     *
+     * @return void
+     */
+    public static function reset()
+    {
+        static::$cache              = null;
+        static::$httpClient         = null;
+        static::$httpMethodOverride = false;
+        static::$httpConditionalGet = false;
+        static::$extensionManager   = null;
+        static::$extensions         = array(
+            'feed' => array(
+                'DublinCore\Feed',
+                'Atom\Feed'
+            ),
+            'entry' => array(
+                'Content\Entry',
+                'DublinCore\Entry',
+                'Atom\Entry'
+            ),
+            'core' => array(
+                'DublinCore\Feed',
+                'Atom\Feed',
+                'Content\Entry',
+                'DublinCore\Entry',
+                'Atom\Entry'
+            )
+        );
+    }
+
+    /**
+     * Register core (default) extensions
+     *
+     * @return void
+     */
+    protected static function registerCoreExtensions()
+    {
+        static::registerExtension('DublinCore');
+        static::registerExtension('Content');
+        static::registerExtension('Atom');
+        static::registerExtension('Slash');
+        static::registerExtension('WellFormedWeb');
+        static::registerExtension('Thread');
+        static::registerExtension('Podcast');
+    }
+
+    /**
+     * Utility method to apply array_unique operation to a multidimensional
+     * array.
+     *
+     * @param array
+     * @return array
+     */
+    public static function arrayUnique(array $array)
+    {
+        foreach ($array as &$value) {
+            $value = serialize($value);
+        }
+        $array = array_unique($array);
+        foreach ($array as &$value) {
+            $value = unserialize($value);
+        }
+        return $array;
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Uri.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Uri.php
new file mode 100644
index 000000000000..c2403c5b75ac
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Uri.php
@@ -0,0 +1,184 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed;
+
+class Uri
+{
+    /**
+     * @var string
+     */
+    protected $fragment;
+
+    /**
+     * @var string
+     */
+    protected $host;
+
+    /**
+     * @var string
+     */
+    protected $pass;
+
+    /**
+     * @var string
+     */
+    protected $path;
+
+    /**
+     * @var int
+     */
+    protected $port;
+
+    /**
+     * @var string
+     */
+    protected $query;
+
+    /**
+     * @var string
+     */
+    protected $scheme;
+
+    /**
+     * @var string
+     */
+    protected $user;
+
+    /**
+     * @var bool
+     */
+    protected $valid;
+
+    /**
+     * Valid schemes
+     */
+    protected $validSchemes = array(
+        'http',
+        'https',
+        'file',
+    );
+
+    /**
+     * @param  string $uri
+     */
+    public function __construct($uri)
+    {
+        $parsed = parse_url($uri);
+        if (false === $parsed) {
+            $this->valid = false;
+            return;
+        }
+
+        $this->scheme   = isset($parsed['scheme'])   ? $parsed['scheme']   : null;
+        $this->host     = isset($parsed['host'])     ? $parsed['host']     : null;
+        $this->port     = isset($parsed['port'])     ? $parsed['port']     : null;
+        $this->user     = isset($parsed['user'])     ? $parsed['user']     : null;
+        $this->pass     = isset($parsed['pass'])     ? $parsed['pass']     : null;
+        $this->path     = isset($parsed['path'])     ? $parsed['path']     : null;
+        $this->query    = isset($parsed['query'])    ? $parsed['query']    : null;
+        $this->fragment = isset($parsed['fragment']) ? $parsed['fragment'] : null;
+    }
+
+    /**
+     * Create an instance
+     *
+     * Useful for chained validations
+     *
+     * @param  string $uri
+     * @return self
+     */
+    public static function factory($uri)
+    {
+        return new static($uri);
+    }
+
+    /**
+     * Retrieve the host
+     *
+     * @return string
+     */
+    public function getHost()
+    {
+        return $this->host;
+    }
+
+    /**
+     * Retrieve the URI path
+     *
+     * @return string
+     */
+    public function getPath()
+    {
+        return $this->path;
+    }
+
+    /**
+     * Retrieve the scheme
+     *
+     * @return string
+     */
+    public function getScheme()
+    {
+        return $this->scheme;
+    }
+
+    /**
+     * Is the URI valid?
+     *
+     * @return bool
+     */
+    public function isValid()
+    {
+        if (false === $this->valid) {
+            return false;
+        }
+
+        if ($this->scheme && !in_array($this->scheme, $this->validSchemes)) {
+            return false;
+        }
+
+        if ($this->host) {
+            if ($this->path && substr($this->path, 0, 1) != '/') {
+                return false;
+            }
+            return true;
+        }
+
+        // no host, but user and/or port... what?
+        if ($this->user || $this->port) {
+            return false;
+        }
+
+        if ($this->path) {
+            // Check path-only (no host) URI
+            if (substr($this->path, 0, 2) == '//') {
+                return false;
+            }
+            return true;
+        }
+
+        if (! ($this->query || $this->fragment)) {
+            // No host, path, query or fragment - this is not a valid URI
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Is the URI absolute?
+     *
+     * @return bool
+     */
+    public function isAbsolute()
+    {
+        return ($this->scheme !== null);
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/AbstractFeed.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/AbstractFeed.php
new file mode 100644
index 000000000000..389a987d2fec
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/AbstractFeed.php
@@ -0,0 +1,848 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer;
+
+use DateTime;
+use Zend\Feed\Uri;
+use Zend\Validator;
+
+class AbstractFeed
+{
+    /**
+     * Contains all Feed level date to append in feed output
+     *
+     * @var array
+     */
+    protected $data = array();
+
+    /**
+     * Holds the value "atom" or "rss" depending on the feed type set when
+     * when last exported.
+     *
+     * @var string
+     */
+    protected $type = null;
+
+    /**
+     * @var $extensions
+     */
+    protected $extensions;
+
+    /**
+     * Constructor: Primarily triggers the registration of core extensions and
+     * loads those appropriate to this data container.
+     *
+     */
+    public function __construct()
+    {
+        Writer::registerCoreExtensions();
+        $this->_loadExtensions();
+    }
+
+    /**
+     * Set a single author
+     *
+     * The following option keys are supported:
+     * 'name'  => (string) The name
+     * 'email' => (string) An optional email
+     * 'uri'   => (string) An optional and valid URI
+     *
+     * @param array $author
+     * @throws Exception\InvalidArgumentException If any value of $author not follow the format.
+     * @return AbstractFeed
+     */
+    public function addAuthor(array $author)
+    {
+        // Check array values
+        if (!array_key_exists('name', $author)
+            || empty($author['name'])
+            || !is_string($author['name'])
+        ) {
+            throw new Exception\InvalidArgumentException(
+                'Invalid parameter: author array must include a "name" key with a non-empty string value');
+        }
+
+        if (isset($author['email'])) {
+            if (empty($author['email']) || !is_string($author['email'])) {
+                throw new Exception\InvalidArgumentException(
+                    'Invalid parameter: "email" array value must be a non-empty string');
+            }
+        }
+        if (isset($author['uri'])) {
+            if (empty($author['uri']) || !is_string($author['uri']) ||
+                !Uri::factory($author['uri'])->isValid()
+            ) {
+                throw new Exception\InvalidArgumentException(
+                    'Invalid parameter: "uri" array value must be a non-empty string and valid URI/IRI');
+            }
+        }
+
+        $this->data['authors'][] = $author;
+
+        return $this;
+    }
+
+    /**
+     * Set an array with feed authors
+     *
+     * @see addAuthor
+     * @param array $authors
+     * @return AbstractFeed
+     */
+    public function addAuthors(array $authors)
+    {
+        foreach ($authors as $author) {
+            $this->addAuthor($author);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Set the copyright entry
+     *
+     * @param  string      $copyright
+     * @throws Exception\InvalidArgumentException
+     * @return AbstractFeed
+     */
+    public function setCopyright($copyright)
+    {
+        if (empty($copyright) || !is_string($copyright)) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: parameter must be a non-empty string');
+        }
+        $this->data['copyright'] = $copyright;
+
+        return $this;
+    }
+
+    /**
+     * Set the feed creation date
+     *
+     * @param null|int|DateTime
+     * @throws Exception\InvalidArgumentException
+     * @return AbstractFeed
+     */
+    public function setDateCreated($date = null)
+    {
+        if ($date === null) {
+            $date = new DateTime();
+        } elseif (is_int($date)) {
+            $date = new DateTime('@' . $date);
+        } elseif (!$date instanceof DateTime) {
+            throw new Exception\InvalidArgumentException('Invalid DateTime object or UNIX Timestamp'
+                                                         . ' passed as parameter');
+        }
+        $this->data['dateCreated'] = $date;
+
+        return $this;
+    }
+
+    /**
+     * Set the feed modification date
+     *
+     * @param null|int|DateTime
+     * @throws Exception\InvalidArgumentException
+     * @return AbstractFeed
+     */
+    public function setDateModified($date = null)
+    {
+        if ($date === null) {
+            $date = new DateTime();
+        } elseif (is_int($date)) {
+            $date = new DateTime('@' . $date);
+        } elseif (!$date instanceof DateTime) {
+            throw new Exception\InvalidArgumentException('Invalid DateTime object or UNIX Timestamp'
+                                                         . ' passed as parameter');
+        }
+        $this->data['dateModified'] = $date;
+
+        return $this;
+    }
+
+    /**
+     * Set the feed last-build date. Ignored for Atom 1.0.
+     *
+     * @param null|int|DateTime
+     * @throws Exception\InvalidArgumentException
+     * @return AbstractFeed
+     */
+    public function setLastBuildDate($date = null)
+    {
+        if ($date === null) {
+            $date = new DateTime();
+        } elseif (is_int($date)) {
+            $date = new DateTime('@' . $date);
+        } elseif (!$date instanceof DateTime) {
+            throw new Exception\InvalidArgumentException('Invalid DateTime object or UNIX Timestamp'
+                                                         . ' passed as parameter');
+        }
+        $this->data['lastBuildDate'] = $date;
+
+        return $this;
+    }
+
+    /**
+     * Set the feed description
+     *
+     * @param string $description
+     * @throws Exception\InvalidArgumentException
+     * @return AbstractFeed
+     */
+    public function setDescription($description)
+    {
+        if (empty($description) || !is_string($description)) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: parameter must be a non-empty string');
+        }
+        $this->data['description'] = $description;
+
+        return $this;
+    }
+
+    /**
+     * Set the feed generator entry
+     *
+     * @param array|string $name
+     * @param null|string $version
+     * @param null|string $uri
+     * @throws Exception\InvalidArgumentException
+     * @return AbstractFeed
+     */
+    public function setGenerator($name, $version = null, $uri = null)
+    {
+        if (is_array($name)) {
+            $data = $name;
+            if (empty($data['name']) || !is_string($data['name'])) {
+                throw new Exception\InvalidArgumentException('Invalid parameter: "name" must be a non-empty string');
+            }
+            $generator = array('name' => $data['name']);
+            if (isset($data['version'])) {
+                if (empty($data['version']) || !is_string($data['version'])) {
+                    throw new Exception\InvalidArgumentException('Invalid parameter: "version" must be a non-empty string');
+                }
+                $generator['version'] = $data['version'];
+            }
+            if (isset($data['uri'])) {
+                if (empty($data['uri']) || !is_string($data['uri']) || !Uri::factory($data['uri'])->isValid()) {
+                    throw new Exception\InvalidArgumentException('Invalid parameter: "uri" must be a non-empty string and a valid URI/IRI');
+                }
+                $generator['uri'] = $data['uri'];
+            }
+        } else {
+            if (empty($name) || !is_string($name)) {
+                throw new Exception\InvalidArgumentException('Invalid parameter: "name" must be a non-empty string');
+            }
+            $generator = array('name' => $name);
+            if (isset($version)) {
+                if (empty($version) || !is_string($version)) {
+                    throw new Exception\InvalidArgumentException('Invalid parameter: "version" must be a non-empty string');
+                }
+                $generator['version'] = $version;
+            }
+            if (isset($uri)) {
+                if (empty($uri) || !is_string($uri) || !Uri::factory($uri)->isValid()) {
+                    throw new Exception\InvalidArgumentException('Invalid parameter: "uri" must be a non-empty string and a valid URI/IRI');
+                }
+                $generator['uri'] = $uri;
+            }
+        }
+        $this->data['generator'] = $generator;
+
+        return $this;
+    }
+
+    /**
+     * Set the feed ID - URI or URN (via PCRE pattern) supported
+     *
+     * @param string $id
+     * @throws Exception\InvalidArgumentException
+     * @return AbstractFeed
+     */
+    public function setId($id)
+    {
+        if ((empty($id) || !is_string($id) || !Uri::factory($id)->isValid())
+            && !preg_match("#^urn:[a-zA-Z0-9][a-zA-Z0-9\-]{1,31}:([a-zA-Z0-9\(\)\+\,\.\:\=\@\;\$\_\!\*\-]|%[0-9a-fA-F]{2})*#", $id)
+            && !$this->_validateTagUri($id)
+        ) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: parameter must be a non-empty string and valid URI/IRI');
+        }
+        $this->data['id'] = $id;
+
+        return $this;
+    }
+
+    /**
+     * Validate a URI using the tag scheme (RFC 4151)
+     *
+     * @param string $id
+     * @return bool
+     */
+    protected function _validateTagUri($id)
+    {
+        if (preg_match('/^tag:(?P<name>.*),(?P<date>\d{4}-?\d{0,2}-?\d{0,2}):(?P<specific>.*)(.*:)*$/', $id, $matches)) {
+            $dvalid = false;
+            $nvalid = false;
+            $date = $matches['date'];
+            $d6 = strtotime($date);
+            if ((strlen($date) == 4) && $date <= date('Y')) {
+                $dvalid = true;
+            } elseif ((strlen($date) == 7) && ($d6 < strtotime("now"))) {
+                $dvalid = true;
+            } elseif ((strlen($date) == 10) && ($d6 < strtotime("now"))) {
+                $dvalid = true;
+            }
+            $validator = new Validator\EmailAddress;
+            if ($validator->isValid($matches['name'])) {
+                $nvalid = true;
+            } else {
+                $nvalid = $validator->isValid('info@' . $matches['name']);
+            }
+            return $dvalid && $nvalid;
+
+        }
+        return false;
+    }
+
+    /**
+     * Set a feed image (URI at minimum). Parameter is a single array with the
+     * required key 'uri'. When rendering as RSS, the required keys are 'uri',
+     * 'title' and 'link'. RSS also specifies three optional parameters 'width',
+     * 'height' and 'description'. Only 'uri' is required and used for Atom rendering.
+     *
+     * @param array $data
+     * @throws Exception\InvalidArgumentException
+     * @return AbstractFeed
+     */
+    public function setImage(array $data)
+    {
+        if (empty($data['uri']) || !is_string($data['uri'])
+            || !Uri::factory($data['uri'])->isValid()
+        ) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: parameter \'uri\''
+            . ' must be a non-empty string and valid URI/IRI');
+        }
+        $this->data['image'] = $data;
+
+        return $this;
+    }
+
+    /**
+     * Set the feed language
+     *
+     * @param string $language
+     * @throws Exception\InvalidArgumentException
+     * @return AbstractFeed
+     */
+    public function setLanguage($language)
+    {
+        if (empty($language) || !is_string($language)) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: parameter must be a non-empty string');
+        }
+        $this->data['language'] = $language;
+
+        return $this;
+    }
+
+    /**
+     * Set a link to the HTML source
+     *
+     * @param string $link
+     * @throws Exception\InvalidArgumentException
+     * @return AbstractFeed
+     */
+    public function setLink($link)
+    {
+        if (empty($link) || !is_string($link) || !Uri::factory($link)->isValid()) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: parameter must be a non-empty string and valid URI/IRI');
+        }
+        $this->data['link'] = $link;
+
+        return $this;
+    }
+
+    /**
+     * Set a link to an XML feed for any feed type/version
+     *
+     * @param string $link
+     * @param string $type
+     * @throws Exception\InvalidArgumentException
+     * @return AbstractFeed
+     */
+    public function setFeedLink($link, $type)
+    {
+        if (empty($link) || !is_string($link) || !Uri::factory($link)->isValid()) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: "link"" must be a non-empty string and valid URI/IRI');
+        }
+        if (!in_array(strtolower($type), array('rss', 'rdf', 'atom'))) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: "type"; You must declare the type of feed the link points to, i.e. RSS, RDF or Atom');
+        }
+        $this->data['feedLinks'][strtolower($type)] = $link;
+
+        return $this;
+    }
+
+    /**
+     * Set the feed title
+     *
+     * @param string $title
+     * @throws Exception\InvalidArgumentException
+     * @return AbstractFeed
+     */
+    public function setTitle($title)
+    {
+        if (empty($title) || !is_string($title)) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: parameter must be a non-empty string');
+        }
+        $this->data['title'] = $title;
+
+        return $this;
+    }
+
+    /**
+     * Set the feed character encoding
+     *
+     * @param string $encoding
+     * @throws Exception\InvalidArgumentException
+     * @return AbstractFeed
+     */
+    public function setEncoding($encoding)
+    {
+        if (empty($encoding) || !is_string($encoding)) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: parameter must be a non-empty string');
+        }
+        $this->data['encoding'] = $encoding;
+
+        return $this;
+    }
+
+    /**
+     * Set the feed's base URL
+     *
+     * @param string $url
+     * @throws Exception\InvalidArgumentException
+     * @return AbstractFeed
+     */
+    public function setBaseUrl($url)
+    {
+        if (empty($url) || !is_string($url) || !Uri::factory($url)->isValid()) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: "url" array value'
+            . ' must be a non-empty string and valid URI/IRI');
+        }
+        $this->data['baseUrl'] = $url;
+
+        return $this;
+    }
+
+    /**
+     * Add a Pubsubhubbub hub endpoint URL
+     *
+     * @param string $url
+     * @throws Exception\InvalidArgumentException
+     * @return AbstractFeed
+     */
+    public function addHub($url)
+    {
+        if (empty($url) || !is_string($url) || !Uri::factory($url)->isValid()) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: "url" array value'
+            . ' must be a non-empty string and valid URI/IRI');
+        }
+        if (!isset($this->data['hubs'])) {
+            $this->data['hubs'] = array();
+        }
+        $this->data['hubs'][] = $url;
+
+        return $this;
+    }
+
+    /**
+     * Add Pubsubhubbub hub endpoint URLs
+     *
+     * @param array $urls
+     * @return AbstractFeed
+     */
+    public function addHubs(array $urls)
+    {
+        foreach ($urls as $url) {
+            $this->addHub($url);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Add a feed category
+     *
+     * @param array $category
+     * @throws Exception\InvalidArgumentException
+     * @return AbstractFeed
+     */
+    public function addCategory(array $category)
+    {
+        if (!isset($category['term'])) {
+            throw new Exception\InvalidArgumentException('Each category must be an array and '
+            . 'contain at least a "term" element containing the machine '
+            . ' readable category name');
+        }
+        if (isset($category['scheme'])) {
+            if (empty($category['scheme'])
+                || !is_string($category['scheme'])
+                || !Uri::factory($category['scheme'])->isValid()
+            ) {
+                throw new Exception\InvalidArgumentException('The Atom scheme or RSS domain of'
+                . ' a category must be a valid URI');
+            }
+        }
+        if (!isset($this->data['categories'])) {
+            $this->data['categories'] = array();
+        }
+        $this->data['categories'][] = $category;
+
+        return $this;
+    }
+
+    /**
+     * Set an array of feed categories
+     *
+     * @param array $categories
+     * @return AbstractFeed
+     */
+    public function addCategories(array $categories)
+    {
+        foreach ($categories as $category) {
+            $this->addCategory($category);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Get a single author
+     *
+     * @param  int $index
+     * @return string|null
+     */
+    public function getAuthor($index = 0)
+    {
+        if (isset($this->data['authors'][$index])) {
+            return $this->data['authors'][$index];
+        }
+
+        return null;
+    }
+
+    /**
+     * Get an array with feed authors
+     *
+     * @return array
+     */
+    public function getAuthors()
+    {
+        if (!array_key_exists('authors', $this->data)) {
+            return null;
+        }
+        return $this->data['authors'];
+    }
+
+    /**
+     * Get the copyright entry
+     *
+     * @return string|null
+     */
+    public function getCopyright()
+    {
+        if (!array_key_exists('copyright', $this->data)) {
+            return null;
+        }
+        return $this->data['copyright'];
+    }
+
+    /**
+     * Get the feed creation date
+     *
+     * @return string|null
+     */
+    public function getDateCreated()
+    {
+        if (!array_key_exists('dateCreated', $this->data)) {
+            return null;
+        }
+        return $this->data['dateCreated'];
+    }
+
+    /**
+     * Get the feed modification date
+     *
+     * @return string|null
+     */
+    public function getDateModified()
+    {
+        if (!array_key_exists('dateModified', $this->data)) {
+            return null;
+        }
+        return $this->data['dateModified'];
+    }
+
+    /**
+     * Get the feed last-build date
+     *
+     * @return string|null
+     */
+    public function getLastBuildDate()
+    {
+        if (!array_key_exists('lastBuildDate', $this->data)) {
+            return null;
+        }
+        return $this->data['lastBuildDate'];
+    }
+
+    /**
+     * Get the feed description
+     *
+     * @return string|null
+     */
+    public function getDescription()
+    {
+        if (!array_key_exists('description', $this->data)) {
+            return null;
+        }
+        return $this->data['description'];
+    }
+
+    /**
+     * Get the feed generator entry
+     *
+     * @return string|null
+     */
+    public function getGenerator()
+    {
+        if (!array_key_exists('generator', $this->data)) {
+            return null;
+        }
+        return $this->data['generator'];
+    }
+
+    /**
+     * Get the feed ID
+     *
+     * @return string|null
+     */
+    public function getId()
+    {
+        if (!array_key_exists('id', $this->data)) {
+            return null;
+        }
+        return $this->data['id'];
+    }
+
+    /**
+     * Get the feed image URI
+     *
+     * @return array
+     */
+    public function getImage()
+    {
+        if (!array_key_exists('image', $this->data)) {
+            return null;
+        }
+        return $this->data['image'];
+    }
+
+    /**
+     * Get the feed language
+     *
+     * @return string|null
+     */
+    public function getLanguage()
+    {
+        if (!array_key_exists('language', $this->data)) {
+            return null;
+        }
+        return $this->data['language'];
+    }
+
+    /**
+     * Get a link to the HTML source
+     *
+     * @return string|null
+     */
+    public function getLink()
+    {
+        if (!array_key_exists('link', $this->data)) {
+            return null;
+        }
+        return $this->data['link'];
+    }
+
+    /**
+     * Get a link to the XML feed
+     *
+     * @return string|null
+     */
+    public function getFeedLinks()
+    {
+        if (!array_key_exists('feedLinks', $this->data)) {
+            return null;
+        }
+        return $this->data['feedLinks'];
+    }
+
+    /**
+     * Get the feed title
+     *
+     * @return string|null
+     */
+    public function getTitle()
+    {
+        if (!array_key_exists('title', $this->data)) {
+            return null;
+        }
+        return $this->data['title'];
+    }
+
+    /**
+     * Get the feed character encoding
+     *
+     * @return string|null
+     */
+    public function getEncoding()
+    {
+        if (!array_key_exists('encoding', $this->data)) {
+            return 'UTF-8';
+        }
+        return $this->data['encoding'];
+    }
+
+    /**
+     * Get the feed's base url
+     *
+     * @return string|null
+     */
+    public function getBaseUrl()
+    {
+        if (!array_key_exists('baseUrl', $this->data)) {
+            return null;
+        }
+        return $this->data['baseUrl'];
+    }
+
+    /**
+     * Get the URLs used as Pubsubhubbub hubs endpoints
+     *
+     * @return string|null
+     */
+    public function getHubs()
+    {
+        if (!array_key_exists('hubs', $this->data)) {
+            return null;
+        }
+        return $this->data['hubs'];
+    }
+
+    /**
+     * Get the feed categories
+     *
+     * @return string|null
+     */
+    public function getCategories()
+    {
+        if (!array_key_exists('categories', $this->data)) {
+            return null;
+        }
+        return $this->data['categories'];
+    }
+
+    /**
+     * Resets the instance and deletes all data
+     *
+     * @return void
+     */
+    public function reset()
+    {
+        $this->data = array();
+    }
+
+    /**
+     * Set the current feed type being exported to "rss" or "atom". This allows
+     * other objects to gracefully choose whether to execute or not, depending
+     * on their appropriateness for the current type, e.g. renderers.
+     *
+     * @param string $type
+     * @return AbstractFeed
+     */
+    public function setType($type)
+    {
+        $this->type = $type;
+        return $this;
+    }
+
+    /**
+     * Retrieve the current or last feed type exported.
+     *
+     * @return string Value will be "rss" or "atom"
+     */
+    public function getType()
+    {
+        return $this->type;
+    }
+
+    /**
+     * Unset a specific data point
+     *
+     * @param string $name
+     * @return AbstractFeed
+     */
+    public function remove($name)
+    {
+        if (isset($this->data[$name])) {
+            unset($this->data[$name]);
+        }
+        return $this;
+    }
+
+    /**
+     * Method overloading: call given method on first extension implementing it
+     *
+     * @param  string $method
+     * @param  array $args
+     * @return mixed
+     * @throws Exception\BadMethodCallException if no extensions implements the method
+     */
+    public function __call($method, $args)
+    {
+        foreach ($this->extensions as $extension) {
+            try {
+                return call_user_func_array(array($extension, $method), $args);
+            } catch (Exception\BadMethodCallException $e) {
+            }
+        }
+        throw new Exception\BadMethodCallException(
+            'Method: ' . $method . ' does not exist and could not be located on a registered Extension'
+        );
+    }
+
+    /**
+     * Load extensions from Zend\Feed\Writer\Writer
+     *
+     * @throws Exception\RuntimeException
+     * @return void
+     */
+    protected function _loadExtensions()
+    {
+        $all     = Writer::getExtensions();
+        $manager = Writer::getExtensionManager();
+        $exts    = $all['feed'];
+        foreach ($exts as $ext) {
+            if (!$manager->has($ext)) {
+                throw new Exception\RuntimeException(sprintf('Unable to load extension "%s"; could not resolve to class', $ext));
+            }
+            $this->extensions[$ext] = $manager->get($ext);
+            $this->extensions[$ext]->setEncoding($this->getEncoding());
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Deleted.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Deleted.php
new file mode 100644
index 000000000000..b9ff321210da
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Deleted.php
@@ -0,0 +1,237 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer;
+
+use DateTime;
+use Zend\Feed\Uri;
+
+/**
+*/
+class Deleted
+{
+
+    /**
+     * Internal array containing all data associated with this entry or item.
+     *
+     * @var array
+     */
+    protected $data = array();
+
+    /**
+     * Holds the value "atom" or "rss" depending on the feed type set when
+     * when last exported.
+     *
+     * @var string
+     */
+    protected $type = null;
+
+    /**
+     * Set the feed character encoding
+     *
+     * @param  $encoding
+     * @throws Exception\InvalidArgumentException
+     * @return string|null
+     * @return Deleted
+     */
+    public function setEncoding($encoding)
+    {
+        if (empty($encoding) || !is_string($encoding)) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: parameter must be a non-empty string');
+        }
+        $this->data['encoding'] = $encoding;
+
+        return $this;
+    }
+
+    /**
+     * Get the feed character encoding
+     *
+     * @return string|null
+     */
+    public function getEncoding()
+    {
+        if (!array_key_exists('encoding', $this->data)) {
+            return 'UTF-8';
+        }
+        return $this->data['encoding'];
+    }
+
+    /**
+     * Unset a specific data point
+     *
+     * @param string $name
+     * @return Deleted
+     */
+    public function remove($name)
+    {
+        if (isset($this->data[$name])) {
+            unset($this->data[$name]);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Set the current feed type being exported to "rss" or "atom". This allows
+     * other objects to gracefully choose whether to execute or not, depending
+     * on their appropriateness for the current type, e.g. renderers.
+     *
+     * @param string $type
+     * @return Deleted
+     */
+    public function setType($type)
+    {
+        $this->type = $type;
+        return $this;
+    }
+
+    /**
+     * Retrieve the current or last feed type exported.
+     *
+     * @return string Value will be "rss" or "atom"
+     */
+    public function getType()
+    {
+        return $this->type;
+    }
+
+    /**
+     * Set reference
+     *
+     * @param $reference
+     * @throws Exception\InvalidArgumentException
+     * @return Deleted
+     */
+    public function setReference($reference)
+    {
+        if (empty($reference) || !is_string($reference)) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: reference must be a non-empty string');
+        }
+        $this->data['reference'] = $reference;
+
+        return $this;
+    }
+
+    /**
+     * @return string
+     */
+    public function getReference()
+    {
+        if (!array_key_exists('reference', $this->data)) {
+            return null;
+        }
+        return $this->data['reference'];
+    }
+
+    /**
+     * Set when
+     *
+     * @param null|string|DateTime $date
+     * @throws Exception\InvalidArgumentException
+     * @return Deleted
+     */
+    public function setWhen($date = null)
+    {
+        if ($date === null) {
+            $date = new DateTime();
+        } elseif (is_int($date)) {
+            $date = new DateTime('@' . $date);
+        } elseif (!$date instanceof DateTime) {
+            throw new Exception\InvalidArgumentException('Invalid DateTime object or UNIX Timestamp'
+            . ' passed as parameter');
+        }
+        $this->data['when'] = $date;
+
+        return $this;
+    }
+
+    /**
+     * @return DateTime
+     */
+    public function getWhen()
+    {
+        if (!array_key_exists('when', $this->data)) {
+            return null;
+        }
+        return $this->data['when'];
+    }
+
+    /**
+     * Set by
+     *
+     * @param array $by
+     * @throws Exception\InvalidArgumentException
+     * @return Deleted
+     */
+    public function setBy(array $by)
+    {
+        $author = array();
+        if (!array_key_exists('name', $by)
+            || empty($by['name'])
+            || !is_string($by['name'])
+        ) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: author array must include a'
+            . ' "name" key with a non-empty string value');
+        }
+        $author['name'] = $by['name'];
+        if (isset($by['email'])) {
+            if (empty($by['email']) || !is_string($by['email'])) {
+                throw new Exception\InvalidArgumentException('Invalid parameter: "email" array'
+                . ' value must be a non-empty string');
+            }
+            $author['email'] = $by['email'];
+        }
+        if (isset($by['uri'])) {
+            if (empty($by['uri'])
+                || !is_string($by['uri'])
+                || !Uri::factory($by['uri'])->isValid()
+            ) {
+                throw new Exception\InvalidArgumentException('Invalid parameter: "uri" array value must'
+                 . ' be a non-empty string and valid URI/IRI');
+            }
+            $author['uri'] = $by['uri'];
+        }
+        $this->data['by'] = $author;
+
+        return $this;
+    }
+
+    /**
+     * @return string
+     */
+    public function getBy()
+    {
+        if (!array_key_exists('by', $this->data)) {
+            return null;
+        }
+        return $this->data['by'];
+    }
+
+    /**
+     * @param string $comment
+     * @return Deleted
+     */
+    public function setComment($comment)
+    {
+        $this->data['comment'] = $comment;
+        return $this;
+    }
+
+    /**
+     * @return string
+     */
+    public function getComment()
+    {
+        if (!array_key_exists('comment', $this->data)) {
+            return null;
+        }
+        return $this->data['comment'];
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Entry.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Entry.php
new file mode 100644
index 000000000000..88a6fea320e2
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Entry.php
@@ -0,0 +1,767 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer;
+
+use DateTime;
+use Zend\Feed\Uri;
+use Zend\Feed\Writer\Exception;
+
+/**
+*/
+class Entry
+{
+
+    /**
+     * Internal array containing all data associated with this entry or item.
+     *
+     * @var array
+     */
+    protected $data = array();
+
+    /**
+     * Registered extensions
+     *
+     * @var array
+     */
+    protected $extensions = array();
+
+    /**
+     * Holds the value "atom" or "rss" depending on the feed type set when
+     * when last exported.
+     *
+     * @var string
+     */
+    protected $type = null;
+
+    /**
+     * Constructor: Primarily triggers the registration of core extensions and
+     * loads those appropriate to this data container.
+     *
+     */
+    public function __construct()
+    {
+        Writer::registerCoreExtensions();
+        $this->_loadExtensions();
+    }
+
+    /**
+     * Set a single author
+     *
+     * The following option keys are supported:
+     * 'name'  => (string) The name
+     * 'email' => (string) An optional email
+     * 'uri'   => (string) An optional and valid URI
+     *
+     * @param array $author
+     * @throws Exception\InvalidArgumentException If any value of $author not follow the format.
+     * @return Entry
+     */
+    public function addAuthor(array $author)
+    {
+        // Check array values
+        if (!array_key_exists('name', $author)
+            || empty($author['name'])
+            || !is_string($author['name'])
+        ) {
+            throw new Exception\InvalidArgumentException(
+                'Invalid parameter: author array must include a "name" key with a non-empty string value');
+        }
+
+        if (isset($author['email'])) {
+            if (empty($author['email']) || !is_string($author['email'])) {
+                throw new Exception\InvalidArgumentException(
+                    'Invalid parameter: "email" array value must be a non-empty string');
+            }
+        }
+        if (isset($author['uri'])) {
+            if (empty($author['uri']) || !is_string($author['uri']) ||
+                !Uri::factory($author['uri'])->isValid()
+            ) {
+                throw new Exception\InvalidArgumentException(
+                    'Invalid parameter: "uri" array value must be a non-empty string and valid URI/IRI');
+            }
+        }
+
+        $this->data['authors'][] = $author;
+
+        return $this;
+    }
+
+    /**
+     * Set an array with feed authors
+     *
+     * @see addAuthor
+     * @param array $authors
+     * @return Entry
+     */
+    public function addAuthors(array $authors)
+    {
+        foreach ($authors as $author) {
+            $this->addAuthor($author);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Set the feed character encoding
+     *
+     * @param string $encoding
+     * @throws Exception\InvalidArgumentException
+     * @return Entry
+     */
+    public function setEncoding($encoding)
+    {
+        if (empty($encoding) || !is_string($encoding)) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: parameter must be a non-empty string');
+        }
+        $this->data['encoding'] = $encoding;
+
+        return $this;
+    }
+
+    /**
+     * Get the feed character encoding
+     *
+     * @return string|null
+     */
+    public function getEncoding()
+    {
+        if (!array_key_exists('encoding', $this->data)) {
+            return 'UTF-8';
+        }
+        return $this->data['encoding'];
+    }
+
+    /**
+     * Set the copyright entry
+     *
+     * @param string $copyright
+     * @throws Exception\InvalidArgumentException
+     * @return Entry
+     */
+    public function setCopyright($copyright)
+    {
+        if (empty($copyright) || !is_string($copyright)) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: parameter must be a non-empty string');
+        }
+        $this->data['copyright'] = $copyright;
+
+        return $this;
+    }
+
+    /**
+     * Set the entry's content
+     *
+     * @param string $content
+     * @throws Exception\InvalidArgumentException
+     * @return Entry
+     */
+    public function setContent($content)
+    {
+        if (empty($content) || !is_string($content)) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: parameter must be a non-empty string');
+        }
+        $this->data['content'] = $content;
+
+        return $this;
+    }
+
+    /**
+     * Set the feed creation date
+     *
+     * @param null|int|DateTime $date
+     * @throws Exception\InvalidArgumentException
+     * @return Entry
+     */
+    public function setDateCreated($date = null)
+    {
+        if ($date === null) {
+            $date = new DateTime();
+        } elseif (is_int($date)) {
+            $date = new DateTime('@' . $date);
+        } elseif (!$date instanceof DateTime) {
+            throw new Exception\InvalidArgumentException('Invalid DateTime object or UNIX Timestamp passed as parameter');
+        }
+        $this->data['dateCreated'] = $date;
+
+        return $this;
+    }
+
+    /**
+     * Set the feed modification date
+     *
+     * @param null|int|DateTime $date
+     * @throws Exception\InvalidArgumentException
+     * @return Entry
+     */
+    public function setDateModified($date = null)
+    {
+        if ($date === null) {
+            $date = new DateTime();
+        } elseif (is_int($date)) {
+            $date = new DateTime('@' . $date);
+        } elseif (!$date instanceof DateTime) {
+            throw new Exception\InvalidArgumentException('Invalid DateTime object or UNIX Timestamp passed as parameter');
+        }
+        $this->data['dateModified'] = $date;
+
+        return $this;
+    }
+
+    /**
+     * Set the feed description
+     *
+     * @param string $description
+     * @throws Exception\InvalidArgumentException
+     * @return Entry
+     */
+    public function setDescription($description)
+    {
+        if (empty($description) || !is_string($description)) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: parameter must be a non-empty string');
+        }
+        $this->data['description'] = $description;
+
+        return $this;
+    }
+
+    /**
+     * Set the feed ID
+     *
+     * @param string $id
+     * @throws Exception\InvalidArgumentException
+     * @return Entry
+     */
+    public function setId($id)
+    {
+        if (empty($id) || !is_string($id)) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: parameter must be a non-empty string');
+        }
+        $this->data['id'] = $id;
+
+        return $this;
+    }
+
+    /**
+     * Set a link to the HTML source of this entry
+     *
+     * @param string $link
+     * @throws Exception\InvalidArgumentException
+     * @return Entry
+     */
+    public function setLink($link)
+    {
+        if (empty($link) || !is_string($link) || !Uri::factory($link)->isValid()) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: parameter must be a non-empty string and valid URI/IRI');
+        }
+        $this->data['link'] = $link;
+
+        return $this;
+    }
+
+    /**
+     * Set the number of comments associated with this entry
+     *
+     * @param int $count
+     * @throws Exception\InvalidArgumentException
+     * @return Entry
+     */
+    public function setCommentCount($count)
+    {
+        if (!is_numeric($count) || (int) $count != $count || (int) $count < 0) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: "count" must be a positive integer number or zero');
+        }
+        $this->data['commentCount'] = (int) $count;
+
+        return $this;
+    }
+
+    /**
+     * Set a link to a HTML page containing comments associated with this entry
+     *
+     * @param string $link
+     * @throws Exception\InvalidArgumentException
+     * @return Entry
+     */
+    public function setCommentLink($link)
+    {
+        if (empty($link) || !is_string($link) || !Uri::factory($link)->isValid()) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: "link" must be a non-empty string and valid URI/IRI');
+        }
+        $this->data['commentLink'] = $link;
+
+        return $this;
+    }
+
+    /**
+     * Set a link to an XML feed for any comments associated with this entry
+     *
+     * @param array $link
+     * @throws Exception\InvalidArgumentException
+     * @return Entry
+     */
+    public function setCommentFeedLink(array $link)
+    {
+        if (!isset($link['uri']) || !is_string($link['uri']) || !Uri::factory($link['uri'])->isValid()) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: "link" must be a non-empty string and valid URI/IRI');
+        }
+        if (!isset($link['type']) || !in_array($link['type'], array('atom', 'rss', 'rdf'))) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: "type" must be one'
+            . ' of "atom", "rss" or "rdf"');
+        }
+        if (!isset($this->data['commentFeedLinks'])) {
+            $this->data['commentFeedLinks'] = array();
+        }
+        $this->data['commentFeedLinks'][] = $link;
+
+        return $this;
+    }
+
+    /**
+     * Set a links to an XML feed for any comments associated with this entry.
+     * Each link is an array with keys "uri" and "type", where type is one of:
+     * "atom", "rss" or "rdf".
+     *
+     * @param array $links
+     * @return Entry
+     */
+    public function setCommentFeedLinks(array $links)
+    {
+        foreach ($links as $link) {
+            $this->setCommentFeedLink($link);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Set the feed title
+     *
+     * @param string $title
+     * @throws Exception\InvalidArgumentException
+     * @return Entry
+     */
+    public function setTitle($title)
+    {
+        if (empty($title) || !is_string($title)) {
+            throw new Exception\InvalidArgumentException('Invalid parameter: parameter must be a non-empty string');
+        }
+        $this->data['title'] = $title;
+
+        return $this;
+    }
+
+    /**
+     * Get an array with feed authors
+     *
+     * @return array
+     */
+    public function getAuthors()
+    {
+        if (!array_key_exists('authors', $this->data)) {
+            return null;
+        }
+        return $this->data['authors'];
+    }
+
+    /**
+     * Get the entry content
+     *
+     * @return string
+     */
+    public function getContent()
+    {
+        if (!array_key_exists('content', $this->data)) {
+            return null;
+        }
+        return $this->data['content'];
+    }
+
+    /**
+     * Get the entry copyright information
+     *
+     * @return string
+     */
+    public function getCopyright()
+    {
+        if (!array_key_exists('copyright', $this->data)) {
+            return null;
+        }
+        return $this->data['copyright'];
+    }
+
+    /**
+     * Get the entry creation date
+     *
+     * @return string
+     */
+    public function getDateCreated()
+    {
+        if (!array_key_exists('dateCreated', $this->data)) {
+            return null;
+        }
+        return $this->data['dateCreated'];
+    }
+
+    /**
+     * Get the entry modification date
+     *
+     * @return string
+     */
+    public function getDateModified()
+    {
+        if (!array_key_exists('dateModified', $this->data)) {
+            return null;
+        }
+        return $this->data['dateModified'];
+    }
+
+    /**
+     * Get the entry description
+     *
+     * @return string
+     */
+    public function getDescription()
+    {
+        if (!array_key_exists('description', $this->data)) {
+            return null;
+        }
+        return $this->data['description'];
+    }
+
+    /**
+     * Get the entry ID
+     *
+     * @return string
+     */
+    public function getId()
+    {
+        if (!array_key_exists('id', $this->data)) {
+            return null;
+        }
+        return $this->data['id'];
+    }
+
+    /**
+     * Get a link to the HTML source
+     *
+     * @return string|null
+     */
+    public function getLink()
+    {
+        if (!array_key_exists('link', $this->data)) {
+            return null;
+        }
+        return $this->data['link'];
+    }
+
+
+    /**
+     * Get all links
+     *
+     * @return array
+     */
+    public function getLinks()
+    {
+        if (!array_key_exists('links', $this->data)) {
+            return null;
+        }
+        return $this->data['links'];
+    }
+
+    /**
+     * Get the entry title
+     *
+     * @return string
+     */
+    public function getTitle()
+    {
+        if (!array_key_exists('title', $this->data)) {
+            return null;
+        }
+        return $this->data['title'];
+    }
+
+    /**
+     * Get the number of comments/replies for current entry
+     *
+     * @return int
+     */
+    public function getCommentCount()
+    {
+        if (!array_key_exists('commentCount', $this->data)) {
+            return null;
+        }
+        return $this->data['commentCount'];
+    }
+
+    /**
+     * Returns a URI pointing to the HTML page where comments can be made on this entry
+     *
+     * @return string
+     */
+    public function getCommentLink()
+    {
+        if (!array_key_exists('commentLink', $this->data)) {
+            return null;
+        }
+        return $this->data['commentLink'];
+    }
+
+    /**
+     * Returns an array of URIs pointing to a feed of all comments for this entry
+     * where the array keys indicate the feed type (atom, rss or rdf).
+     *
+     * @return string
+     */
+    public function getCommentFeedLinks()
+    {
+        if (!array_key_exists('commentFeedLinks', $this->data)) {
+            return null;
+        }
+        return $this->data['commentFeedLinks'];
+    }
+
+    /**
+     * Add a entry category
+     *
+     * @param array $category
+     * @throws Exception\InvalidArgumentException
+     * @return Entry
+     */
+    public function addCategory(array $category)
+    {
+        if (!isset($category['term'])) {
+            throw new Exception\InvalidArgumentException('Each category must be an array and '
+            . 'contain at least a "term" element containing the machine '
+            . ' readable category name');
+        }
+        if (isset($category['scheme'])) {
+            if (empty($category['scheme'])
+                || !is_string($category['scheme'])
+                || !Uri::factory($category['scheme'])->isValid()
+            ) {
+                throw new Exception\InvalidArgumentException('The Atom scheme or RSS domain of'
+                . ' a category must be a valid URI');
+            }
+        }
+        if (!isset($this->data['categories'])) {
+            $this->data['categories'] = array();
+        }
+        $this->data['categories'][] = $category;
+
+        return $this;
+    }
+
+    /**
+     * Set an array of entry categories
+     *
+     * @param array $categories
+     * @return Entry
+     */
+    public function addCategories(array $categories)
+    {
+        foreach ($categories as $category) {
+            $this->addCategory($category);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Get the entry categories
+     *
+     * @return string|null
+     */
+    public function getCategories()
+    {
+        if (!array_key_exists('categories', $this->data)) {
+            return null;
+        }
+        return $this->data['categories'];
+    }
+
+    /**
+     * Adds an enclosure to the entry. The array parameter may contain the
+     * keys 'uri', 'type' and 'length'. Only 'uri' is required for Atom, though the
+     * others must also be provided or RSS rendering (where they are required)
+     * will throw an Exception.
+     *
+     * @param array $enclosure
+     * @throws Exception\InvalidArgumentException
+     * @return Entry
+     */
+    public function setEnclosure(array $enclosure)
+    {
+        if (!isset($enclosure['uri'])) {
+            throw new Exception\InvalidArgumentException('Enclosure "uri" is not set');
+        }
+        if (!Uri::factory($enclosure['uri'])->isValid()) {
+            throw new Exception\InvalidArgumentException('Enclosure "uri" is not a valid URI/IRI');
+        }
+        $this->data['enclosure'] = $enclosure;
+
+        return $this;
+    }
+
+    /**
+     * Retrieve an array of all enclosures to be added to entry.
+     *
+     * @return array
+     */
+    public function getEnclosure()
+    {
+        if (!array_key_exists('enclosure', $this->data)) {
+            return null;
+        }
+        return $this->data['enclosure'];
+    }
+
+    /**
+     * Unset a specific data point
+     *
+     * @param string $name
+     * @return Entry
+     */
+    public function remove($name)
+    {
+        if (isset($this->data[$name])) {
+            unset($this->data[$name]);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Get registered extensions
+     *
+     * @return array
+     */
+    public function getExtensions()
+    {
+        return $this->extensions;
+    }
+
+    /**
+     * Return an Extension object with the matching name (postfixed with _Entry)
+     *
+     * @param string $name
+     * @return object
+     */
+    public function getExtension($name)
+    {
+        if (array_key_exists($name . '\\Entry', $this->extensions)) {
+            return $this->extensions[$name . '\\Entry'];
+        }
+        return null;
+    }
+
+    /**
+     * Set the current feed type being exported to "rss" or "atom". This allows
+     * other objects to gracefully choose whether to execute or not, depending
+     * on their appropriateness for the current type, e.g. renderers.
+     *
+     * @param string $type
+     * @return Entry
+     */
+    public function setType($type)
+    {
+        $this->type = $type;
+        return $this;
+    }
+
+    /**
+     * Retrieve the current or last feed type exported.
+     *
+     * @return string Value will be "rss" or "atom"
+     */
+    public function getType()
+    {
+        return $this->type;
+    }
+
+    /**
+     * Method overloading: call given method on first extension implementing it
+     *
+     * @param  string $method
+     * @param  array $args
+     * @return mixed
+     * @throws Exception\BadMethodCallException if no extensions implements the method
+     */
+    public function __call($method, $args)
+    {
+        foreach ($this->extensions as $extension) {
+            try {
+                return call_user_func_array(array($extension, $method), $args);
+            } catch (\BadMethodCallException $e) {
+            }
+        }
+        throw new Exception\BadMethodCallException('Method: ' . $method
+            . ' does not exist and could not be located on a registered Extension');
+    }
+
+    /**
+     * Creates a new Zend\Feed\Writer\Source data container for use. This is NOT
+     * added to the current feed automatically, but is necessary to create a
+     * container with some initial values preset based on the current feed data.
+     *
+     * @return Source
+     */
+    public function createSource()
+    {
+        $source = new Source;
+        if ($this->getEncoding()) {
+            $source->setEncoding($this->getEncoding());
+        }
+        $source->setType($this->getType());
+        return $source;
+    }
+
+    /**
+     * Appends a Zend\Feed\Writer\Entry object representing a new entry/item
+     * the feed data container's internal group of entries.
+     *
+     * @param Source $source
+     * @return Entry
+     */
+    public function setSource(Source $source)
+    {
+        $this->data['source'] = $source;
+        return $this;
+    }
+
+    /**
+     * @return Source
+     */
+    public function getSource()
+    {
+        if (isset($this->data['source'])) {
+            return $this->data['source'];
+        }
+        return null;
+    }
+
+    /**
+     * Load extensions from Zend\Feed\Writer\Writer
+     *
+     * @return void
+     */
+    protected function _loadExtensions()
+    {
+        $all     = Writer::getExtensions();
+        $manager = Writer::getExtensionManager();
+        $exts    = $all['entry'];
+        foreach ($exts as $ext) {
+            $this->extensions[$ext] = $manager->get($ext);
+            $this->extensions[$ext]->setEncoding($this->getEncoding());
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Exception/BadMethodCallException.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Exception/BadMethodCallException.php
new file mode 100644
index 000000000000..e969d219e09b
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Exception/BadMethodCallException.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Exception;
+
+use Zend\Feed\Exception;
+
+/**
+ * Feed exceptions
+ *
+ * Class to represent exceptions that occur during Feed operations.
+ */
+class BadMethodCallException
+    extends Exception\BadMethodCallException
+    implements ExceptionInterface
+{}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Exception/ExceptionInterface.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Exception/ExceptionInterface.php
new file mode 100644
index 000000000000..dbcd27964b2f
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Exception/ExceptionInterface.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Exception;
+
+/**
+ * Feed exceptions
+ *
+ * Interface to represent exceptions that occur during Feed operations.
+ */
+interface ExceptionInterface
+{
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Exception/InvalidArgumentException.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Exception/InvalidArgumentException.php
new file mode 100644
index 000000000000..971eead3862d
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Exception/InvalidArgumentException.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Exception;
+
+use Zend\Feed\Exception;
+
+/**
+ * Feed exceptions
+ *
+ * Class to represent exceptions that occur during Feed operations.
+ */
+class InvalidArgumentException
+    extends Exception\InvalidArgumentException
+    implements ExceptionInterface
+{}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Exception/RuntimeException.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Exception/RuntimeException.php
new file mode 100644
index 000000000000..2c37bdaf68bb
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Exception/RuntimeException.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Exception;
+
+use Zend\Feed\Exception;
+
+class RuntimeException
+    extends Exception\RuntimeException
+    implements ExceptionInterface
+{}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/AbstractRenderer.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/AbstractRenderer.php
new file mode 100644
index 000000000000..7927e735ea07
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/AbstractRenderer.php
@@ -0,0 +1,164 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Extension;
+
+use DOMDocument;
+use DOMElement;
+
+/**
+*/
+abstract class AbstractRenderer implements RendererInterface
+{
+    /**
+     * @var DOMDocument
+     */
+    protected $dom = null;
+
+    /**
+     * @var mixed
+     */
+    protected $entry = null;
+
+    /**
+     * @var DOMElement
+     */
+    protected $base = null;
+
+    /**
+     * @var mixed
+     */
+    protected $container = null;
+
+    /**
+     * @var string
+     */
+    protected $type = null;
+
+    /**
+     * @var DOMElement
+     */
+    protected $rootElement = null;
+
+    /**
+     * Encoding of all text values
+     *
+     * @var string
+     */
+    protected $encoding = 'UTF-8';
+
+    /**
+     * Set the data container
+     *
+     * @param  mixed $container
+     * @return AbstractRenderer
+     */
+    public function setDataContainer($container)
+    {
+        $this->container = $container;
+        return $this;
+    }
+
+    /**
+     * Set feed encoding
+     *
+     * @param  string $enc
+     * @return AbstractRenderer
+     */
+    public function setEncoding($enc)
+    {
+        $this->encoding = $enc;
+        return $this;
+    }
+
+    /**
+     * Get feed encoding
+     *
+     * @return string
+     */
+    public function getEncoding()
+    {
+        return $this->encoding;
+    }
+
+    /**
+     * Set DOMDocument and DOMElement on which to operate
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $base
+     * @return AbstractRenderer
+     */
+    public function setDomDocument(DOMDocument $dom, DOMElement $base)
+    {
+        $this->dom  = $dom;
+        $this->base = $base;
+        return $this;
+    }
+
+    /**
+     * Get data container being rendered
+     *
+     * @return mixed
+     */
+    public function getDataContainer()
+    {
+        return $this->container;
+    }
+
+    /**
+     * Set feed type
+     *
+     * @param  string $type
+     * @return AbstractRenderer
+     */
+    public function setType($type)
+    {
+        $this->type = $type;
+        return $this;
+    }
+
+    /**
+     * Get feedtype
+     *
+     * @return string
+     */
+    public function getType()
+    {
+        return $this->type;
+    }
+
+    /**
+     * Set root element of document
+     *
+     * @param  DOMElement $root
+     * @return AbstractRenderer
+     */
+    public function setRootElement(DOMElement $root)
+    {
+        $this->rootElement = $root;
+        return $this;
+    }
+
+    /**
+     * Get root element
+     *
+     * @return DOMElement
+     */
+    public function getRootElement()
+    {
+        return $this->rootElement;
+    }
+
+    /**
+     * Append namespaces to feed
+     *
+     * @return void
+     */
+    abstract protected function _appendNamespaces();
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/Atom/Renderer/Feed.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/Atom/Renderer/Feed.php
new file mode 100644
index 000000000000..1d7023e311d3
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/Atom/Renderer/Feed.php
@@ -0,0 +1,109 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Extension\Atom\Renderer;
+
+use DOMDocument;
+use DOMElement;
+use Zend\Feed\Writer\Extension;
+
+/**
+*/
+class Feed extends Extension\AbstractRenderer
+{
+
+    /**
+     * Set to TRUE if a rendering method actually renders something. This
+     * is used to prevent premature appending of a XML namespace declaration
+     * until an element which requires it is actually appended.
+     *
+     * @var bool
+     */
+    protected $called = false;
+
+    /**
+     * Render feed
+     *
+     * @return void
+     */
+    public function render()
+    {
+        /**
+         * RSS 2.0 only. Used mainly to include Atom links and
+         * Pubsubhubbub Hub endpoint URIs under the Atom namespace
+         */
+        if (strtolower($this->getType()) == 'atom') {
+            return;
+        }
+        $this->_setFeedLinks($this->dom, $this->base);
+        $this->_setHubs($this->dom, $this->base);
+        if ($this->called) {
+            $this->_appendNamespaces();
+        }
+    }
+
+    /**
+     * Append namespaces to root element of feed
+     *
+     * @return void
+     */
+    protected function _appendNamespaces()
+    {
+        $this->getRootElement()->setAttribute('xmlns:atom',
+            'http://www.w3.org/2005/Atom');
+    }
+
+    /**
+     * Set feed link elements
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setFeedLinks(DOMDocument $dom, DOMElement $root)
+    {
+        $flinks = $this->getDataContainer()->getFeedLinks();
+        if (!$flinks || empty($flinks)) {
+            return;
+        }
+        foreach ($flinks as $type => $href) {
+            if (strtolower($type) == $this->getType()) { // issue 2605
+                $mime  = 'application/' . strtolower($type) . '+xml';
+                $flink = $dom->createElement('atom:link');
+                $root->appendChild($flink);
+                $flink->setAttribute('rel', 'self');
+                $flink->setAttribute('type', $mime);
+                $flink->setAttribute('href', $href);
+            }
+        }
+        $this->called = true;
+    }
+
+    /**
+     * Set PuSH hubs
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setHubs(DOMDocument $dom, DOMElement $root)
+    {
+        $hubs = $this->getDataContainer()->getHubs();
+        if (!$hubs || empty($hubs)) {
+            return;
+        }
+        foreach ($hubs as $hubUrl) {
+            $hub = $dom->createElement('atom:link');
+            $hub->setAttribute('rel', 'hub');
+            $hub->setAttribute('href', $hubUrl);
+            $root->appendChild($hub);
+        }
+        $this->called = true;
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/Content/Renderer/Entry.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/Content/Renderer/Entry.php
new file mode 100644
index 000000000000..8785fb7320ba
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/Content/Renderer/Entry.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Extension\Content\Renderer;
+
+use DOMDocument;
+use DOMElement;
+use Zend\Feed\Writer\Extension;
+
+/**
+*/
+class Entry extends Extension\AbstractRenderer
+{
+
+    /**
+     * Set to TRUE if a rendering method actually renders something. This
+     * is used to prevent premature appending of a XML namespace declaration
+     * until an element which requires it is actually appended.
+     *
+     * @var bool
+     */
+    protected $called = false;
+
+    /**
+     * Render entry
+     *
+     * @return void
+     */
+    public function render()
+    {
+        if (strtolower($this->getType()) == 'atom') {
+            return;
+        }
+        $this->_setContent($this->dom, $this->base);
+        if ($this->called) {
+            $this->_appendNamespaces();
+        }
+    }
+
+    /**
+     * Append namespaces to root element
+     *
+     * @return void
+     */
+    protected function _appendNamespaces()
+    {
+        $this->getRootElement()->setAttribute('xmlns:content',
+            'http://purl.org/rss/1.0/modules/content/');
+    }
+
+    /**
+     * Set entry content
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setContent(DOMDocument $dom, DOMElement $root)
+    {
+        $content = $this->getDataContainer()->getContent();
+        if (!$content) {
+            return;
+        }
+        $element = $dom->createElement('content:encoded');
+        $root->appendChild($element);
+        $cdata = $dom->createCDATASection($content);
+        $element->appendChild($cdata);
+        $this->called = true;
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/DublinCore/Renderer/Entry.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/DublinCore/Renderer/Entry.php
new file mode 100644
index 000000000000..fffefd54f28a
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/DublinCore/Renderer/Entry.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Extension\DublinCore\Renderer;
+
+use DOMDocument;
+use DOMElement;
+use Zend\Feed\Writer\Extension;
+
+/**
+*/
+class Entry extends Extension\AbstractRenderer
+{
+
+    /**
+     * Set to TRUE if a rendering method actually renders something. This
+     * is used to prevent premature appending of a XML namespace declaration
+     * until an element which requires it is actually appended.
+     *
+     * @var bool
+     */
+    protected $called = false;
+
+    /**
+     * Render entry
+     *
+     * @return void
+     */
+    public function render()
+    {
+        if (strtolower($this->getType()) == 'atom') {
+            return;
+        }
+        $this->_setAuthors($this->dom, $this->base);
+        if ($this->called) {
+            $this->_appendNamespaces();
+        }
+    }
+
+    /**
+     * Append namespaces to entry
+     *
+     * @return void
+     */
+    protected function _appendNamespaces()
+    {
+        $this->getRootElement()->setAttribute('xmlns:dc',
+            'http://purl.org/dc/elements/1.1/');
+    }
+
+    /**
+     * Set entry author elements
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setAuthors(DOMDocument $dom, DOMElement $root)
+    {
+        $authors = $this->getDataContainer()->getAuthors();
+        if (!$authors || empty($authors)) {
+            return;
+        }
+        foreach ($authors as $data) {
+            $author = $this->dom->createElement('dc:creator');
+            if (array_key_exists('name', $data)) {
+                $text = $dom->createTextNode($data['name']);
+                $author->appendChild($text);
+                $root->appendChild($author);
+            }
+        }
+        $this->called = true;
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/DublinCore/Renderer/Feed.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/DublinCore/Renderer/Feed.php
new file mode 100644
index 000000000000..ceb3fac3f3d3
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/DublinCore/Renderer/Feed.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Extension\DublinCore\Renderer;
+
+use DOMDocument;
+use DOMElement;
+use Zend\Feed\Writer\Extension;
+
+/**
+*/
+class Feed extends Extension\AbstractRenderer
+{
+
+    /**
+     * Set to TRUE if a rendering method actually renders something. This
+     * is used to prevent premature appending of a XML namespace declaration
+     * until an element which requires it is actually appended.
+     *
+     * @var bool
+     */
+    protected $called = false;
+
+    /**
+     * Render feed
+     *
+     * @return void
+     */
+    public function render()
+    {
+        if (strtolower($this->getType()) == 'atom') {
+            return;
+        }
+        $this->_setAuthors($this->dom, $this->base);
+        if ($this->called) {
+            $this->_appendNamespaces();
+        }
+    }
+
+    /**
+     * Append namespaces to feed element
+     *
+     * @return void
+     */
+    protected function _appendNamespaces()
+    {
+        $this->getRootElement()->setAttribute('xmlns:dc',
+            'http://purl.org/dc/elements/1.1/');
+    }
+
+    /**
+     * Set feed authors
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setAuthors(DOMDocument $dom, DOMElement $root)
+    {
+        $authors = $this->getDataContainer()->getAuthors();
+        if (!$authors || empty($authors)) {
+            return;
+        }
+        foreach ($authors as $data) {
+            $author = $this->dom->createElement('dc:creator');
+            if (array_key_exists('name', $data)) {
+                $text = $dom->createTextNode($data['name']);
+                $author->appendChild($text);
+                $root->appendChild($author);
+            }
+        }
+        $this->called = true;
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/ITunes/Entry.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/ITunes/Entry.php
new file mode 100644
index 000000000000..f136293e8738
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/ITunes/Entry.php
@@ -0,0 +1,246 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Extension\ITunes;
+
+use Zend\Feed\Writer;
+use Zend\Feed\Writer\Extension;
+use Zend\Stdlib\StringUtils;
+use Zend\Stdlib\StringWrapper\StringWrapperInterface;
+
+/**
+*/
+class Entry
+{
+    /**
+     * Array of Feed data for rendering by Extension's renderers
+     *
+     * @var array
+     */
+    protected $data = array();
+
+    /**
+     * Encoding of all text values
+     *
+     * @var string
+     */
+    protected $encoding = 'UTF-8';
+
+    /**
+     * The used string wrapper supporting encoding
+     *
+     * @var StringWrapperInterface
+     */
+    protected $stringWrapper;
+
+    public function __construct()
+    {
+        $this->stringWrapper = StringUtils::getWrapper($this->encoding);
+    }
+
+    /**
+     * Set feed encoding
+     *
+     * @param  string $enc
+     * @return Entry
+     */
+    public function setEncoding($enc)
+    {
+        $this->stringWrapper = StringUtils::getWrapper($enc);
+        $this->encoding      = $enc;
+        return $this;
+    }
+
+    /**
+     * Get feed encoding
+     *
+     * @return string
+     */
+    public function getEncoding()
+    {
+        return $this->encoding;
+    }
+
+    /**
+     * Set a block value of "yes" or "no". You may also set an empty string.
+     *
+     * @param  string
+     * @return Entry
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    public function setItunesBlock($value)
+    {
+        if (!ctype_alpha($value) && strlen($value) > 0) {
+            throw new Writer\Exception\InvalidArgumentException('invalid parameter: "block" may only'
+            . ' contain alphabetic characters');
+        }
+
+        if ($this->stringWrapper->strlen($value) > 255) {
+            throw new Writer\Exception\InvalidArgumentException('invalid parameter: "block" may only'
+            . ' contain a maximum of 255 characters');
+        }
+        $this->data['block'] = $value;
+    }
+
+    /**
+     * Add authors to itunes entry
+     *
+     * @param  array $values
+     * @return Entry
+     */
+    public function addItunesAuthors(array $values)
+    {
+        foreach ($values as $value) {
+            $this->addItunesAuthor($value);
+        }
+        return $this;
+    }
+
+    /**
+     * Add author to itunes entry
+     *
+     * @param  string $value
+     * @return Entry
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    public function addItunesAuthor($value)
+    {
+        if ($this->stringWrapper->strlen($value) > 255) {
+            throw new Writer\Exception\InvalidArgumentException('invalid parameter: any "author" may only'
+            . ' contain a maximum of 255 characters each');
+        }
+        if (!isset($this->data['authors'])) {
+            $this->data['authors'] = array();
+        }
+        $this->data['authors'][] = $value;
+        return $this;
+    }
+
+    /**
+     * Set duration
+     *
+     * @param  int $value
+     * @return Entry
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    public function setItunesDuration($value)
+    {
+        $value = (string) $value;
+        if (!ctype_digit($value)
+            && !preg_match("/^\d+:[0-5]{1}[0-9]{1}$/", $value)
+            && !preg_match("/^\d+:[0-5]{1}[0-9]{1}:[0-5]{1}[0-9]{1}$/", $value)
+        ) {
+            throw new Writer\Exception\InvalidArgumentException('invalid parameter: "duration" may only'
+            . ' be of a specified [[HH:]MM:]SS format');
+        }
+        $this->data['duration'] = $value;
+        return $this;
+    }
+
+    /**
+     * Set "explicit" flag
+     *
+     * @param  bool $value
+     * @return Entry
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    public function setItunesExplicit($value)
+    {
+        if (!in_array($value, array('yes', 'no', 'clean'))) {
+            throw new Writer\Exception\InvalidArgumentException('invalid parameter: "explicit" may only'
+            . ' be one of "yes", "no" or "clean"');
+        }
+        $this->data['explicit'] = $value;
+        return $this;
+    }
+
+    /**
+     * Set keywords
+     *
+     * @param  array $value
+     * @return Entry
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    public function setItunesKeywords(array $value)
+    {
+        if (count($value) > 12) {
+            throw new Writer\Exception\InvalidArgumentException('invalid parameter: "keywords" may only'
+            . ' contain a maximum of 12 terms');
+        }
+
+        $concat = implode(',', $value);
+        if ($this->stringWrapper->strlen($concat) > 255) {
+            throw new Writer\Exception\InvalidArgumentException('invalid parameter: "keywords" may only'
+            . ' have a concatenated length of 255 chars where terms are delimited'
+            . ' by a comma');
+        }
+        $this->data['keywords'] = $value;
+        return $this;
+    }
+
+    /**
+     * Set subtitle
+     *
+     * @param  string $value
+     * @return Entry
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    public function setItunesSubtitle($value)
+    {
+        if ($this->stringWrapper->strlen($value) > 255) {
+            throw new Writer\Exception\InvalidArgumentException('invalid parameter: "subtitle" may only'
+            . ' contain a maximum of 255 characters');
+        }
+        $this->data['subtitle'] = $value;
+        return $this;
+    }
+
+    /**
+     * Set summary
+     *
+     * @param  string $value
+     * @return Entry
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    public function setItunesSummary($value)
+    {
+        if ($this->stringWrapper->strlen($value) > 4000) {
+            throw new Writer\Exception\InvalidArgumentException('invalid parameter: "summary" may only'
+            . ' contain a maximum of 4000 characters');
+        }
+        $this->data['summary'] = $value;
+        return $this;
+    }
+
+    /**
+     * Overloading to itunes specific setters
+     *
+     * @param  string $method
+     * @param  array $params
+     * @throws Writer\Exception\BadMethodCallException
+     * @return mixed
+     */
+    public function __call($method, array $params)
+    {
+        $point = lcfirst(substr($method, 9));
+        if (!method_exists($this, 'setItunes' . ucfirst($point))
+            && !method_exists($this, 'addItunes' . ucfirst($point))
+        ) {
+            throw new Writer\Exception\BadMethodCallException(
+                'invalid method: ' . $method
+            );
+        }
+        if (!array_key_exists($point, $this->data)
+            || empty($this->data[$point])
+        ) {
+            return null;
+        }
+        return $this->data[$point];
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/ITunes/Feed.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/ITunes/Feed.php
new file mode 100644
index 000000000000..7e6c5ac55e46
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/ITunes/Feed.php
@@ -0,0 +1,362 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Extension\ITunes;
+
+use Zend\Feed\Uri;
+use Zend\Feed\Writer;
+use Zend\Stdlib\StringUtils;
+use Zend\Stdlib\StringWrapper\StringWrapperInterface;
+
+/**
+*/
+class Feed
+{
+    /**
+     * Array of Feed data for rendering by Extension's renderers
+     *
+     * @var array
+     */
+    protected $data = array();
+
+    /**
+     * Encoding of all text values
+     *
+     * @var string
+     */
+    protected $encoding = 'UTF-8';
+
+    /**
+     * The used string wrapper supporting encoding
+     *
+     * @var StringWrapperInterface
+     */
+    protected $stringWrapper;
+
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->stringWrapper = StringUtils::getWrapper($this->encoding);
+    }
+
+    /**
+     * Set feed encoding
+     *
+     * @param  string $enc
+     * @return Feed
+     */
+    public function setEncoding($enc)
+    {
+        $this->stringWrapper = StringUtils::getWrapper($enc);
+        $this->encoding      = $enc;
+        return $this;
+    }
+
+    /**
+     * Get feed encoding
+     *
+     * @return string
+     */
+    public function getEncoding()
+    {
+        return $this->encoding;
+    }
+
+    /**
+     * Set a block value of "yes" or "no". You may also set an empty string.
+     *
+     * @param  string
+     * @return Feed
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    public function setItunesBlock($value)
+    {
+        if (!ctype_alpha($value) && strlen($value) > 0) {
+            throw new Writer\Exception\InvalidArgumentException('invalid parameter: "block" may only'
+            . ' contain alphabetic characters');
+        }
+        if ($this->stringWrapper->strlen($value) > 255) {
+            throw new Writer\Exception\InvalidArgumentException('invalid parameter: "block" may only'
+            . ' contain a maximum of 255 characters');
+        }
+        $this->data['block'] = $value;
+        return $this;
+    }
+
+    /**
+     * Add feed authors
+     *
+     * @param  array $values
+     * @return Feed
+     */
+    public function addItunesAuthors(array $values)
+    {
+        foreach ($values as $value) {
+            $this->addItunesAuthor($value);
+        }
+        return $this;
+    }
+
+    /**
+     * Add feed author
+     *
+     * @param  string $value
+     * @return Feed
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    public function addItunesAuthor($value)
+    {
+        if ($this->stringWrapper->strlen($value) > 255) {
+            throw new Writer\Exception\InvalidArgumentException('invalid parameter: any "author" may only'
+            . ' contain a maximum of 255 characters each');
+        }
+        if (!isset($this->data['authors'])) {
+            $this->data['authors'] = array();
+        }
+        $this->data['authors'][] = $value;
+        return $this;
+    }
+
+    /**
+     * Set feed categories
+     *
+     * @param  array $values
+     * @return Feed
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    public function setItunesCategories(array $values)
+    {
+        if (!isset($this->data['categories'])) {
+            $this->data['categories'] = array();
+        }
+        foreach ($values as $key => $value) {
+            if (!is_array($value)) {
+                if ($this->stringWrapper->strlen($value) > 255) {
+                    throw new Writer\Exception\InvalidArgumentException('invalid parameter: any "category" may only'
+                    . ' contain a maximum of 255 characters each');
+                }
+                $this->data['categories'][] = $value;
+            } else {
+                if ($this->stringWrapper->strlen($key) > 255) {
+                    throw new Writer\Exception\InvalidArgumentException('invalid parameter: any "category" may only'
+                    . ' contain a maximum of 255 characters each');
+                }
+                $this->data['categories'][$key] = array();
+                foreach ($value as $val) {
+                    if ($this->stringWrapper->strlen($val) > 255) {
+                        throw new Writer\Exception\InvalidArgumentException('invalid parameter: any "category" may only'
+                        . ' contain a maximum of 255 characters each');
+                    }
+                    $this->data['categories'][$key][] = $val;
+                }
+            }
+        }
+        return $this;
+    }
+
+    /**
+     * Set feed image (icon)
+     *
+     * @param  string $value
+     * @return Feed
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    public function setItunesImage($value)
+    {
+        if (!Uri::factory($value)->isValid()) {
+            throw new Writer\Exception\InvalidArgumentException('invalid parameter: "image" may only'
+            . ' be a valid URI/IRI');
+        }
+        if (!in_array(substr($value, -3), array('jpg', 'png'))) {
+            throw new Writer\Exception\InvalidArgumentException('invalid parameter: "image" may only'
+            . ' use file extension "jpg" or "png" which must be the last three'
+            . ' characters of the URI (i.e. no query string or fragment)');
+        }
+        $this->data['image'] = $value;
+        return $this;
+    }
+
+    /**
+     * Set feed cumulative duration
+     *
+     * @param  string $value
+     * @return Feed
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    public function setItunesDuration($value)
+    {
+        $value = (string) $value;
+        if (!ctype_digit($value)
+            && !preg_match("/^\d+:[0-5]{1}[0-9]{1}$/", $value)
+            && !preg_match("/^\d+:[0-5]{1}[0-9]{1}:[0-5]{1}[0-9]{1}$/", $value)
+        ) {
+            throw new Writer\Exception\InvalidArgumentException('invalid parameter: "duration" may only'
+            . ' be of a specified [[HH:]MM:]SS format');
+        }
+        $this->data['duration'] = $value;
+        return $this;
+    }
+
+    /**
+     * Set "explicit" flag
+     *
+     * @param  bool $value
+     * @return Feed
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    public function setItunesExplicit($value)
+    {
+        if (!in_array($value, array('yes', 'no', 'clean'))) {
+            throw new Writer\Exception\InvalidArgumentException('invalid parameter: "explicit" may only'
+            . ' be one of "yes", "no" or "clean"');
+        }
+        $this->data['explicit'] = $value;
+        return $this;
+    }
+
+    /**
+     * Set feed keywords
+     *
+     * @param  array $value
+     * @return Feed
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    public function setItunesKeywords(array $value)
+    {
+        if (count($value) > 12) {
+            throw new Writer\Exception\InvalidArgumentException('invalid parameter: "keywords" may only'
+            . ' contain a maximum of 12 terms');
+        }
+        $concat = implode(',', $value);
+        if ($this->stringWrapper->strlen($concat) > 255) {
+            throw new Writer\Exception\InvalidArgumentException('invalid parameter: "keywords" may only'
+            . ' have a concatenated length of 255 chars where terms are delimited'
+            . ' by a comma');
+        }
+        $this->data['keywords'] = $value;
+        return $this;
+    }
+
+    /**
+     * Set new feed URL
+     *
+     * @param  string $value
+     * @return Feed
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    public function setItunesNewFeedUrl($value)
+    {
+        if (!Uri::factory($value)->isValid()) {
+            throw new Writer\Exception\InvalidArgumentException('invalid parameter: "newFeedUrl" may only'
+            . ' be a valid URI/IRI');
+        }
+        $this->data['newFeedUrl'] = $value;
+        return $this;
+    }
+
+    /**
+     * Add feed owners
+     *
+     * @param  array $values
+     * @return Feed
+     */
+    public function addItunesOwners(array $values)
+    {
+        foreach ($values as $value) {
+            $this->addItunesOwner($value);
+        }
+        return $this;
+    }
+
+    /**
+     * Add feed owner
+     *
+     * @param  array $value
+     * @return Feed
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    public function addItunesOwner(array $value)
+    {
+        if (!isset($value['name']) || !isset($value['email'])) {
+            throw new Writer\Exception\InvalidArgumentException('invalid parameter: any "owner" must'
+            . ' be an array containing keys "name" and "email"');
+        }
+        if ($this->stringWrapper->strlen($value['name']) > 255
+            || $this->stringWrapper->strlen($value['email']) > 255
+        ) {
+            throw new Writer\Exception\InvalidArgumentException('invalid parameter: any "owner" may only'
+            . ' contain a maximum of 255 characters each for "name" and "email"');
+        }
+        if (!isset($this->data['owners'])) {
+            $this->data['owners'] = array();
+        }
+        $this->data['owners'][] = $value;
+        return $this;
+    }
+
+    /**
+     * Set feed subtitle
+     *
+     * @param  string $value
+     * @return Feed
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    public function setItunesSubtitle($value)
+    {
+        if ($this->stringWrapper->strlen($value) > 255) {
+            throw new Writer\Exception\InvalidArgumentException('invalid parameter: "subtitle" may only'
+            . ' contain a maximum of 255 characters');
+        }
+        $this->data['subtitle'] = $value;
+        return $this;
+    }
+
+    /**
+     * Set feed summary
+     *
+     * @param  string $value
+     * @return Feed
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    public function setItunesSummary($value)
+    {
+        if ($this->stringWrapper->strlen($value) > 4000) {
+            throw new Writer\Exception\InvalidArgumentException('invalid parameter: "summary" may only'
+            . ' contain a maximum of 4000 characters');
+        }
+        $this->data['summary'] = $value;
+        return $this;
+    }
+
+    /**
+     * Overloading: proxy to internal setters
+     *
+     * @param  string $method
+     * @param  array $params
+     * @return mixed
+     * @throws Writer\Exception\BadMethodCallException
+     */
+    public function __call($method, array $params)
+    {
+        $point = lcfirst(substr($method, 9));
+        if (!method_exists($this, 'setItunes' . ucfirst($point))
+            && !method_exists($this, 'addItunes' . ucfirst($point))
+        ) {
+            throw new Writer\Exception\BadMethodCallException(
+                'invalid method: ' . $method
+            );
+        }
+        if (!array_key_exists($point, $this->data) || empty($this->data[$point])) {
+            return null;
+        }
+        return $this->data[$point];
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/ITunes/Renderer/Entry.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/ITunes/Renderer/Entry.php
new file mode 100644
index 000000000000..b46d10c5373c
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/ITunes/Renderer/Entry.php
@@ -0,0 +1,200 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Extension\ITunes\Renderer;
+
+use DOMDocument;
+use DOMElement;
+use Zend\Feed\Writer\Extension;
+
+/**
+*/
+class Entry extends Extension\AbstractRenderer
+{
+    /**
+     * Set to TRUE if a rendering method actually renders something. This
+     * is used to prevent premature appending of a XML namespace declaration
+     * until an element which requires it is actually appended.
+     *
+     * @var bool
+     */
+    protected $called = false;
+
+    /**
+     * Render entry
+     *
+     * @return void
+     */
+    public function render()
+    {
+        $this->_setAuthors($this->dom, $this->base);
+        $this->_setBlock($this->dom, $this->base);
+        $this->_setDuration($this->dom, $this->base);
+        $this->_setExplicit($this->dom, $this->base);
+        $this->_setKeywords($this->dom, $this->base);
+        $this->_setSubtitle($this->dom, $this->base);
+        $this->_setSummary($this->dom, $this->base);
+        if ($this->called) {
+            $this->_appendNamespaces();
+        }
+    }
+
+    /**
+     * Append namespaces to entry root
+     *
+     * @return void
+     */
+    protected function _appendNamespaces()
+    {
+        $this->getRootElement()->setAttribute('xmlns:itunes',
+            'http://www.itunes.com/dtds/podcast-1.0.dtd');
+    }
+
+    /**
+     * Set entry authors
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setAuthors(DOMDocument $dom, DOMElement $root)
+    {
+        $authors = $this->getDataContainer()->getItunesAuthors();
+        if (!$authors || empty($authors)) {
+            return;
+        }
+        foreach ($authors as $author) {
+            $el = $dom->createElement('itunes:author');
+            $text = $dom->createTextNode($author);
+            $el->appendChild($text);
+            $root->appendChild($el);
+            $this->called = true;
+        }
+    }
+
+    /**
+     * Set itunes block
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setBlock(DOMDocument $dom, DOMElement $root)
+    {
+        $block = $this->getDataContainer()->getItunesBlock();
+        if ($block === null) {
+            return;
+        }
+        $el = $dom->createElement('itunes:block');
+        $text = $dom->createTextNode($block);
+        $el->appendChild($text);
+        $root->appendChild($el);
+        $this->called = true;
+    }
+
+    /**
+     * Set entry duration
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setDuration(DOMDocument $dom, DOMElement $root)
+    {
+        $duration = $this->getDataContainer()->getItunesDuration();
+        if (!$duration) {
+            return;
+        }
+        $el = $dom->createElement('itunes:duration');
+        $text = $dom->createTextNode($duration);
+        $el->appendChild($text);
+        $root->appendChild($el);
+        $this->called = true;
+    }
+
+    /**
+     * Set explicit flag
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setExplicit(DOMDocument $dom, DOMElement $root)
+    {
+        $explicit = $this->getDataContainer()->getItunesExplicit();
+        if ($explicit === null) {
+            return;
+        }
+        $el = $dom->createElement('itunes:explicit');
+        $text = $dom->createTextNode($explicit);
+        $el->appendChild($text);
+        $root->appendChild($el);
+        $this->called = true;
+    }
+
+    /**
+     * Set entry keywords
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setKeywords(DOMDocument $dom, DOMElement $root)
+    {
+        $keywords = $this->getDataContainer()->getItunesKeywords();
+        if (!$keywords || empty($keywords)) {
+            return;
+        }
+        $el = $dom->createElement('itunes:keywords');
+        $text = $dom->createTextNode(implode(',', $keywords));
+        $el->appendChild($text);
+        $root->appendChild($el);
+        $this->called = true;
+    }
+
+    /**
+     * Set entry subtitle
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setSubtitle(DOMDocument $dom, DOMElement $root)
+    {
+        $subtitle = $this->getDataContainer()->getItunesSubtitle();
+        if (!$subtitle) {
+            return;
+        }
+        $el = $dom->createElement('itunes:subtitle');
+        $text = $dom->createTextNode($subtitle);
+        $el->appendChild($text);
+        $root->appendChild($el);
+        $this->called = true;
+    }
+
+    /**
+     * Set entry summary
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setSummary(DOMDocument $dom, DOMElement $root)
+    {
+        $summary = $this->getDataContainer()->getItunesSummary();
+        if (!$summary) {
+            return;
+        }
+        $el = $dom->createElement('itunes:summary');
+        $text = $dom->createTextNode($summary);
+        $el->appendChild($text);
+        $root->appendChild($el);
+        $this->called = true;
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/ITunes/Renderer/Feed.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/ITunes/Renderer/Feed.php
new file mode 100644
index 000000000000..9799681a0c3f
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/ITunes/Renderer/Feed.php
@@ -0,0 +1,304 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Extension\ITunes\Renderer;
+
+use DOMDocument;
+use DOMElement;
+use Zend\Feed\Writer\Extension;
+
+/**
+*/
+class Feed extends Extension\AbstractRenderer
+{
+
+    /**
+     * Set to TRUE if a rendering method actually renders something. This
+     * is used to prevent premature appending of a XML namespace declaration
+     * until an element which requires it is actually appended.
+     *
+     * @var bool
+     */
+    protected $called = false;
+
+    /**
+     * Render feed
+     *
+     * @return void
+     */
+    public function render()
+    {
+        $this->_setAuthors($this->dom, $this->base);
+        $this->_setBlock($this->dom, $this->base);
+        $this->_setCategories($this->dom, $this->base);
+        $this->_setImage($this->dom, $this->base);
+        $this->_setDuration($this->dom, $this->base);
+        $this->_setExplicit($this->dom, $this->base);
+        $this->_setKeywords($this->dom, $this->base);
+        $this->_setNewFeedUrl($this->dom, $this->base);
+        $this->_setOwners($this->dom, $this->base);
+        $this->_setSubtitle($this->dom, $this->base);
+        $this->_setSummary($this->dom, $this->base);
+        if ($this->called) {
+            $this->_appendNamespaces();
+        }
+    }
+
+    /**
+     * Append feed namespaces
+     *
+     * @return void
+     */
+    protected function _appendNamespaces()
+    {
+        $this->getRootElement()->setAttribute('xmlns:itunes',
+            'http://www.itunes.com/dtds/podcast-1.0.dtd');
+    }
+
+    /**
+     * Set feed authors
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setAuthors(DOMDocument $dom, DOMElement $root)
+    {
+        $authors = $this->getDataContainer()->getItunesAuthors();
+        if (!$authors || empty($authors)) {
+            return;
+        }
+        foreach ($authors as $author) {
+            $el = $dom->createElement('itunes:author');
+            $text = $dom->createTextNode($author);
+            $el->appendChild($text);
+            $root->appendChild($el);
+        }
+        $this->called = true;
+    }
+
+    /**
+     * Set feed itunes block
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setBlock(DOMDocument $dom, DOMElement $root)
+    {
+        $block = $this->getDataContainer()->getItunesBlock();
+        if ($block === null) {
+            return;
+        }
+        $el = $dom->createElement('itunes:block');
+        $text = $dom->createTextNode($block);
+        $el->appendChild($text);
+        $root->appendChild($el);
+        $this->called = true;
+    }
+
+    /**
+     * Set feed categories
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setCategories(DOMDocument $dom, DOMElement $root)
+    {
+        $cats = $this->getDataContainer()->getItunesCategories();
+        if (!$cats || empty($cats)) {
+            return;
+        }
+        foreach ($cats as $key => $cat) {
+            if (!is_array($cat)) {
+                $el = $dom->createElement('itunes:category');
+                $el->setAttribute('text', $cat);
+                $root->appendChild($el);
+            } else {
+                $el = $dom->createElement('itunes:category');
+                $el->setAttribute('text', $key);
+                $root->appendChild($el);
+                foreach ($cat as $subcat) {
+                    $el2 = $dom->createElement('itunes:category');
+                    $el2->setAttribute('text', $subcat);
+                    $el->appendChild($el2);
+                }
+            }
+        }
+        $this->called = true;
+    }
+
+    /**
+     * Set feed image (icon)
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setImage(DOMDocument $dom, DOMElement $root)
+    {
+        $image = $this->getDataContainer()->getItunesImage();
+        if (!$image) {
+            return;
+        }
+        $el = $dom->createElement('itunes:image');
+        $el->setAttribute('href', $image);
+        $root->appendChild($el);
+        $this->called = true;
+    }
+
+    /**
+     * Set feed cumulative duration
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setDuration(DOMDocument $dom, DOMElement $root)
+    {
+        $duration = $this->getDataContainer()->getItunesDuration();
+        if (!$duration) {
+            return;
+        }
+        $el = $dom->createElement('itunes:duration');
+        $text = $dom->createTextNode($duration);
+        $el->appendChild($text);
+        $root->appendChild($el);
+        $this->called = true;
+    }
+
+    /**
+     * Set explicit flag
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setExplicit(DOMDocument $dom, DOMElement $root)
+    {
+        $explicit = $this->getDataContainer()->getItunesExplicit();
+        if ($explicit === null) {
+            return;
+        }
+        $el = $dom->createElement('itunes:explicit');
+        $text = $dom->createTextNode($explicit);
+        $el->appendChild($text);
+        $root->appendChild($el);
+        $this->called = true;
+    }
+
+    /**
+     * Set feed keywords
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setKeywords(DOMDocument $dom, DOMElement $root)
+    {
+        $keywords = $this->getDataContainer()->getItunesKeywords();
+        if (!$keywords || empty($keywords)) {
+            return;
+        }
+        $el = $dom->createElement('itunes:keywords');
+        $text = $dom->createTextNode(implode(',', $keywords));
+        $el->appendChild($text);
+        $root->appendChild($el);
+        $this->called = true;
+    }
+
+    /**
+     * Set feed's new URL
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setNewFeedUrl(DOMDocument $dom, DOMElement $root)
+    {
+        $url = $this->getDataContainer()->getItunesNewFeedUrl();
+        if (!$url) {
+            return;
+        }
+        $el = $dom->createElement('itunes:new-feed-url');
+        $text = $dom->createTextNode($url);
+        $el->appendChild($text);
+        $root->appendChild($el);
+        $this->called = true;
+    }
+
+    /**
+     * Set feed owners
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setOwners(DOMDocument $dom, DOMElement $root)
+    {
+        $owners = $this->getDataContainer()->getItunesOwners();
+        if (!$owners || empty($owners)) {
+            return;
+        }
+        foreach ($owners as $owner) {
+            $el = $dom->createElement('itunes:owner');
+            $name = $dom->createElement('itunes:name');
+            $text = $dom->createTextNode($owner['name']);
+            $name->appendChild($text);
+            $email = $dom->createElement('itunes:email');
+            $text = $dom->createTextNode($owner['email']);
+            $email->appendChild($text);
+            $root->appendChild($el);
+            $el->appendChild($name);
+            $el->appendChild($email);
+        }
+        $this->called = true;
+    }
+
+    /**
+     * Set feed subtitle
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setSubtitle(DOMDocument $dom, DOMElement $root)
+    {
+        $subtitle = $this->getDataContainer()->getItunesSubtitle();
+        if (!$subtitle) {
+            return;
+        }
+        $el = $dom->createElement('itunes:subtitle');
+        $text = $dom->createTextNode($subtitle);
+        $el->appendChild($text);
+        $root->appendChild($el);
+        $this->called = true;
+    }
+
+    /**
+     * Set feed summary
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setSummary(DOMDocument $dom, DOMElement $root)
+    {
+        $summary = $this->getDataContainer()->getItunesSummary();
+        if (!$summary) {
+            return;
+        }
+        $el = $dom->createElement('itunes:summary');
+        $text = $dom->createTextNode($summary);
+        $el->appendChild($text);
+        $root->appendChild($el);
+        $this->called = true;
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/RendererInterface.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/RendererInterface.php
new file mode 100644
index 000000000000..032313d6fd3f
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/RendererInterface.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Extension;
+
+use DOMDocument;
+use DOMElement;
+
+/**
+*/
+interface RendererInterface
+{
+    /**
+     * Set the data container
+     *
+     * @param  mixed $container
+     * @return void
+     */
+    public function setDataContainer($container);
+
+    /**
+     * Retrieve container
+     *
+     * @return mixed
+     */
+    public function getDataContainer();
+
+    /**
+     * Set DOMDocument and DOMElement on which to operate
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $base
+     * @return void
+     */
+    public function setDomDocument(DOMDocument $dom, DOMElement $base);
+
+    /**
+     * Render
+     *
+     * @return void
+     */
+    public function render();
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/Slash/Renderer/Entry.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/Slash/Renderer/Entry.php
new file mode 100644
index 000000000000..80adb515a601
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/Slash/Renderer/Entry.php
@@ -0,0 +1,75 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Extension\Slash\Renderer;
+
+use DOMDocument;
+use DOMElement;
+use Zend\Feed\Writer\Extension;
+
+/**
+*/
+class Entry extends Extension\AbstractRenderer
+{
+
+    /**
+     * Set to TRUE if a rendering method actually renders something. This
+     * is used to prevent premature appending of a XML namespace declaration
+     * until an element which requires it is actually appended.
+     *
+     * @var bool
+     */
+    protected $called = false;
+
+    /**
+     * Render entry
+     *
+     * @return void
+     */
+    public function render()
+    {
+        if (strtolower($this->getType()) == 'atom') {
+            return; // RSS 2.0 only
+        }
+        $this->_setCommentCount($this->dom, $this->base);
+        if ($this->called) {
+            $this->_appendNamespaces();
+        }
+    }
+
+    /**
+     * Append entry namespaces
+     *
+     * @return void
+     */
+    protected function _appendNamespaces()
+    {
+        $this->getRootElement()->setAttribute('xmlns:slash',
+            'http://purl.org/rss/1.0/modules/slash/');
+    }
+
+    /**
+     * Set entry comment count
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setCommentCount(DOMDocument $dom, DOMElement $root)
+    {
+        $count = $this->getDataContainer()->getCommentCount();
+        if (!$count) {
+            $count = 0;
+        }
+        $tcount = $this->dom->createElement('slash:comments');
+        $tcount->nodeValue = $count;
+        $root->appendChild($tcount);
+        $this->called = true;
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/Threading/Renderer/Entry.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/Threading/Renderer/Entry.php
new file mode 100644
index 000000000000..ee66b8f2635a
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/Threading/Renderer/Entry.php
@@ -0,0 +1,129 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Extension\Threading\Renderer;
+
+use DOMDocument;
+use DOMElement;
+use Zend\Feed\Writer\Extension;
+
+/**
+*/
+class Entry extends Extension\AbstractRenderer
+{
+
+    /**
+     * Set to TRUE if a rendering method actually renders something. This
+     * is used to prevent premature appending of a XML namespace declaration
+     * until an element which requires it is actually appended.
+     *
+     * @var bool
+     */
+    protected $called = false;
+
+    /**
+     * Render entry
+     *
+     * @return void
+     */
+    public function render()
+    {
+        if (strtolower($this->getType()) == 'rss') {
+            return; // Atom 1.0 only
+        }
+        $this->_setCommentLink($this->dom, $this->base);
+        $this->_setCommentFeedLinks($this->dom, $this->base);
+        $this->_setCommentCount($this->dom, $this->base);
+        if ($this->called) {
+            $this->_appendNamespaces();
+        }
+    }
+
+    /**
+     * Append entry namespaces
+     *
+     * @return void
+     */
+    protected function _appendNamespaces()
+    {
+        $this->getRootElement()->setAttribute('xmlns:thr',
+            'http://purl.org/syndication/thread/1.0');
+    }
+
+    /**
+     * Set comment link
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setCommentLink(DOMDocument $dom, DOMElement $root)
+    {
+        $link = $this->getDataContainer()->getCommentLink();
+        if (!$link) {
+            return;
+        }
+        $clink = $this->dom->createElement('link');
+        $clink->setAttribute('rel', 'replies');
+        $clink->setAttribute('type', 'text/html');
+        $clink->setAttribute('href', $link);
+        $count = $this->getDataContainer()->getCommentCount();
+        if ($count !== null) {
+            $clink->setAttribute('thr:count', $count);
+        }
+        $root->appendChild($clink);
+        $this->called = true;
+    }
+
+    /**
+     * Set comment feed links
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setCommentFeedLinks(DOMDocument $dom, DOMElement $root)
+    {
+        $links = $this->getDataContainer()->getCommentFeedLinks();
+        if (!$links || empty($links)) {
+            return;
+        }
+        foreach ($links as $link) {
+            $flink = $this->dom->createElement('link');
+            $flink->setAttribute('rel', 'replies');
+            $flink->setAttribute('type', 'application/' . $link['type'] . '+xml');
+            $flink->setAttribute('href', $link['uri']);
+            $count = $this->getDataContainer()->getCommentCount();
+            if ($count !== null) {
+                $flink->setAttribute('thr:count', $count);
+            }
+            $root->appendChild($flink);
+            $this->called = true;
+        }
+    }
+
+    /**
+     * Set entry comment count
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setCommentCount(DOMDocument $dom, DOMElement $root)
+    {
+        $count = $this->getDataContainer()->getCommentCount();
+        if ($count === null) {
+            return;
+        }
+        $tcount = $this->dom->createElement('thr:total');
+        $tcount->nodeValue = $count;
+        $root->appendChild($tcount);
+        $this->called = true;
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/WellFormedWeb/Renderer/Entry.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/WellFormedWeb/Renderer/Entry.php
new file mode 100644
index 000000000000..f5da0b0d27c6
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Extension/WellFormedWeb/Renderer/Entry.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Extension\WellFormedWeb\Renderer;
+
+use DOMDocument;
+use DOMElement;
+use Zend\Feed\Writer\Extension;
+
+/**
+*/
+class Entry extends Extension\AbstractRenderer
+{
+
+    /**
+     * Set to TRUE if a rendering method actually renders something. This
+     * is used to prevent premature appending of a XML namespace declaration
+     * until an element which requires it is actually appended.
+     *
+     * @var bool
+     */
+    protected $called = false;
+
+    /**
+     * Render entry
+     *
+     * @return void
+     */
+    public function render()
+    {
+        if (strtolower($this->getType()) == 'atom') {
+            return; // RSS 2.0 only
+        }
+        $this->_setCommentFeedLinks($this->dom, $this->base);
+        if ($this->called) {
+            $this->_appendNamespaces();
+        }
+    }
+
+    /**
+     * Append entry namespaces
+     *
+     * @return void
+     */
+    protected function _appendNamespaces()
+    {
+        $this->getRootElement()->setAttribute('xmlns:wfw',
+            'http://wellformedweb.org/CommentAPI/');
+    }
+
+    /**
+     * Set entry comment feed links
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setCommentFeedLinks(DOMDocument $dom, DOMElement $root)
+    {
+        $links = $this->getDataContainer()->getCommentFeedLinks();
+        if (!$links || empty($links)) {
+            return;
+        }
+        foreach ($links as $link) {
+            if ($link['type'] == 'rss') {
+                $flink = $this->dom->createElement('wfw:commentRss');
+                $text = $dom->createTextNode($link['uri']);
+                $flink->appendChild($text);
+                $root->appendChild($flink);
+            }
+        }
+        $this->called = true;
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/ExtensionManager.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/ExtensionManager.php
new file mode 100644
index 000000000000..0bb4ce0ff03c
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/ExtensionManager.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer;
+
+/**
+ * Default implementation of ExtensionManagerInterface
+ *
+ * Decorator of ExtensionPluginManager.
+ */
+class ExtensionManager implements ExtensionManagerInterface
+{
+    protected $pluginManager;
+
+    /**
+     * Constructor
+     *
+     * Seeds the extension manager with a plugin manager; if none provided,
+     * creates an instance.
+     *
+     * @param  null|ExtensionPluginManager $pluginManager
+     */
+    public function __construct(ExtensionPluginManager $pluginManager = null)
+    {
+        if (null === $pluginManager) {
+            $pluginManager = new ExtensionPluginManager();
+        }
+        $this->pluginManager = $pluginManager;
+    }
+
+    /**
+     * Method overloading
+     *
+     * Proxy to composed ExtensionPluginManager instance.
+     *
+     * @param  string $method
+     * @param  array $args
+     * @return mixed
+     * @throws Exception\BadMethodCallException
+     */
+    public function __call($method, $args)
+    {
+        if (!method_exists($this->pluginManager, $method)) {
+            throw new Exception\BadMethodCallException(sprintf(
+                'Method by name of %s does not exist in %s',
+                $method,
+                __CLASS__
+            ));
+        }
+        return call_user_func_array(array($this->pluginManager, $method), $args);
+    }
+
+    /**
+     * Get the named extension
+     *
+     * @param  string $name
+     * @return Extension\AbstractEntry|Extension\AbstractFeed
+     */
+    public function get($name)
+    {
+        return $this->pluginManager->get($name);
+    }
+
+    /**
+     * Do we have the named extension?
+     *
+     * @param  string $name
+     * @return bool
+     */
+    public function has($name)
+    {
+        return $this->pluginManager->has($name);
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/ExtensionManagerInterface.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/ExtensionManagerInterface.php
new file mode 100644
index 000000000000..358e187a86ad
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/ExtensionManagerInterface.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer;
+
+interface ExtensionManagerInterface
+{
+    /**
+     * Do we have the extension?
+     *
+     * @param  string $extension
+     * @return bool
+     */
+    public function has($extension);
+
+    /**
+     * Retrieve the extension
+     *
+     * @param  string $extension
+     * @return mixed
+     */
+    public function get($extension);
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/ExtensionPluginManager.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/ExtensionPluginManager.php
new file mode 100644
index 000000000000..575794eb3f5b
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/ExtensionPluginManager.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer;
+
+use Zend\ServiceManager\AbstractPluginManager;
+
+/**
+ * Plugin manager implementation for feed writer extensions
+ *
+ * Validation checks that we have an Entry, Feed, or Extension\AbstractRenderer.
+ */
+class ExtensionPluginManager extends AbstractPluginManager
+{
+    /**
+     * Default set of extension classes
+     *
+     * @var array
+     */
+    protected $invokableClasses = array(
+        'atomrendererfeed'           => 'Zend\Feed\Writer\Extension\Atom\Renderer\Feed',
+        'contentrendererentry'       => 'Zend\Feed\Writer\Extension\Content\Renderer\Entry',
+        'dublincorerendererentry'    => 'Zend\Feed\Writer\Extension\DublinCore\Renderer\Entry',
+        'dublincorerendererfeed'     => 'Zend\Feed\Writer\Extension\DublinCore\Renderer\Feed',
+        'itunesentry'                => 'Zend\Feed\Writer\Extension\ITunes\Entry',
+        'itunesfeed'                 => 'Zend\Feed\Writer\Extension\ITunes\Feed',
+        'itunesrendererentry'        => 'Zend\Feed\Writer\Extension\ITunes\Renderer\Entry',
+        'itunesrendererfeed'         => 'Zend\Feed\Writer\Extension\ITunes\Renderer\Feed',
+        'slashrendererentry'         => 'Zend\Feed\Writer\Extension\Slash\Renderer\Entry',
+        'threadingrendererentry'     => 'Zend\Feed\Writer\Extension\Threading\Renderer\Entry',
+        'wellformedwebrendererentry' => 'Zend\Feed\Writer\Extension\WellFormedWeb\Renderer\Entry',
+    );
+
+    /**
+     * Do not share instances
+     *
+     * @var bool
+     */
+    protected $shareByDefault = false;
+
+    /**
+     * Validate the plugin
+     *
+     * Checks that the extension loaded is of a valid type.
+     *
+     * @param  mixed $plugin
+     * @return void
+     * @throws Exception\InvalidArgumentException if invalid
+     */
+    public function validatePlugin($plugin)
+    {
+        if ($plugin instanceof Extension\AbstractRenderer) {
+            // we're okay
+            return;
+        }
+
+        if ('Feed' == substr(get_class($plugin), -4)) {
+            // we're okay
+            return;
+        }
+
+        if ('Entry' == substr(get_class($plugin), -5)) {
+            // we're okay
+            return;
+        }
+
+        throw new Exception\InvalidArgumentException(sprintf(
+            'Plugin of type %s is invalid; must implement %s\Extension\RendererInterface '
+            . 'or the classname must end in "Feed" or "Entry"',
+            (is_object($plugin) ? get_class($plugin) : gettype($plugin)),
+            __NAMESPACE__
+        ));
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Feed.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Feed.php
new file mode 100644
index 000000000000..0922082c66cc
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Feed.php
@@ -0,0 +1,241 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer;
+
+use Countable;
+use Iterator;
+use Zend\Feed\Writer\Renderer;
+
+/**
+*/
+class Feed extends AbstractFeed implements Iterator, Countable
+{
+
+    /**
+     * Contains all entry objects
+     *
+     * @var array
+     */
+    protected $entries = array();
+
+    /**
+     * A pointer for the iterator to keep track of the entries array
+     *
+     * @var int
+     */
+    protected $entriesKey = 0;
+
+    /**
+     * Creates a new Zend\Feed\Writer\Entry data container for use. This is NOT
+     * added to the current feed automatically, but is necessary to create a
+     * container with some initial values preset based on the current feed data.
+     *
+     * @return \Zend\Feed\Writer\Entry
+     */
+    public function createEntry()
+    {
+        $entry = new Entry;
+        if ($this->getEncoding()) {
+            $entry->setEncoding($this->getEncoding());
+        }
+        $entry->setType($this->getType());
+        return $entry;
+    }
+
+    /**
+     * Appends a Zend\Feed\Writer\Deleted object representing a new entry tombstone
+     * to the feed data container's internal group of entries.
+     *
+     * @param Deleted $deleted
+     * @return void
+     */
+    public function addTombstone(Deleted $deleted)
+    {
+        $this->entries[] = $deleted;
+    }
+
+    /**
+     * Creates a new Zend\Feed\Writer\Deleted data container for use. This is NOT
+     * added to the current feed automatically, but is necessary to create a
+     * container with some initial values preset based on the current feed data.
+     *
+     * @return Deleted
+     */
+    public function createTombstone()
+    {
+        $deleted = new Deleted;
+        if ($this->getEncoding()) {
+            $deleted->setEncoding($this->getEncoding());
+        }
+        $deleted->setType($this->getType());
+        return $deleted;
+    }
+
+    /**
+     * Appends a Zend\Feed\Writer\Entry object representing a new entry/item
+     * the feed data container's internal group of entries.
+     *
+     * @param Entry $entry
+     * @return Feed
+     */
+    public function addEntry(Entry $entry)
+    {
+        $this->entries[] = $entry;
+        return $this;
+    }
+
+    /**
+     * Removes a specific indexed entry from the internal queue. Entries must be
+     * added to a feed container in order to be indexed.
+     *
+     * @param int $index
+     * @throws Exception\InvalidArgumentException
+     * @return Feed
+     */
+    public function removeEntry($index)
+    {
+        if (!isset($this->entries[$index])) {
+            throw new Exception\InvalidArgumentException('Undefined index: ' . $index . '. Entry does not exist.');
+        }
+        unset($this->entries[$index]);
+
+        return $this;
+    }
+
+    /**
+     * Retrieve a specific indexed entry from the internal queue. Entries must be
+     * added to a feed container in order to be indexed.
+     *
+     * @param int $index
+     * @throws Exception\InvalidArgumentException
+     */
+    public function getEntry($index = 0)
+    {
+        if (isset($this->entries[$index])) {
+            return $this->entries[$index];
+        }
+        throw new Exception\InvalidArgumentException('Undefined index: ' . $index . '. Entry does not exist.');
+    }
+
+    /**
+     * Orders all indexed entries by date, thus offering date ordered readable
+     * content where a parser (or Homo Sapien) ignores the generic rule that
+     * XML element order is irrelevant and has no intrinsic meaning.
+     *
+     * Using this method will alter the original indexation.
+     *
+     * @return Feed
+     */
+    public function orderByDate()
+    {
+        /**
+         * Could do with some improvement for performance perhaps
+         */
+        $timestamp = time();
+        $entries = array();
+        foreach ($this->entries as $entry) {
+            if ($entry->getDateModified()) {
+                $timestamp = (int) $entry->getDateModified()->getTimestamp();
+            } elseif ($entry->getDateCreated()) {
+                $timestamp = (int) $entry->getDateCreated()->getTimestamp();
+            }
+            $entries[$timestamp] = $entry;
+        }
+        krsort($entries, SORT_NUMERIC);
+        $this->entries = array_values($entries);
+
+        return $this;
+    }
+
+    /**
+     * Get the number of feed entries.
+     * Required by the Iterator interface.
+     *
+     * @return int
+     */
+    public function count()
+    {
+        return count($this->entries);
+    }
+
+    /**
+     * Return the current entry
+     *
+     * @return Entry
+     */
+    public function current()
+    {
+        return $this->entries[$this->key()];
+    }
+
+    /**
+     * Return the current feed key
+     *
+     * @return mixed
+     */
+    public function key()
+    {
+        return $this->entriesKey;
+    }
+
+    /**
+     * Move the feed pointer forward
+     *
+     * @return void
+     */
+    public function next()
+    {
+        ++$this->entriesKey;
+    }
+
+    /**
+     * Reset the pointer in the feed object
+     *
+     * @return void
+     */
+    public function rewind()
+    {
+        $this->entriesKey = 0;
+    }
+
+    /**
+     * Check to see if the iterator is still valid
+     *
+     * @return bool
+     */
+    public function valid()
+    {
+        return 0 <= $this->entriesKey && $this->entriesKey < $this->count();
+    }
+
+    /**
+     * Attempt to build and return the feed resulting from the data set
+     *
+     * @param  string  $type The feed type "rss" or "atom" to export as
+     * @param  bool    $ignoreExceptions
+     * @throws Exception\InvalidArgumentException
+     * @return string
+     */
+    public function export($type, $ignoreExceptions = false)
+    {
+        $this->setType(strtolower($type));
+        $type = ucfirst($this->getType());
+        if ($type !== 'Rss' && $type !== 'Atom') {
+            throw new Exception\InvalidArgumentException('Invalid feed type specified: ' . $type . '.'
+            . ' Should be one of "rss" or "atom".');
+        }
+        $renderClass = 'Zend\\Feed\\Writer\\Renderer\\Feed\\' . $type;
+        $renderer = new $renderClass($this);
+        if ($ignoreExceptions) {
+            $renderer->ignoreExceptions();
+        }
+        return $renderer->render()->saveXml();
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/FeedFactory.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/FeedFactory.php
new file mode 100644
index 000000000000..9cf8fbae6271
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/FeedFactory.php
@@ -0,0 +1,127 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer;
+
+use Traversable;
+
+abstract class FeedFactory
+{
+    /**
+     * Create and return a Feed based on data provided.
+     *
+     * @param  array|Traversable $data
+     * @throws Exception\InvalidArgumentException
+     * @return Feed
+     */
+    public static function factory($data)
+    {
+        if (!is_array($data) && !$data instanceof Traversable) {
+            throw new Exception\InvalidArgumentException(sprintf(
+                '%s expects an array or Traversable argument; received "%s"',
+                __METHOD__,
+                (is_object($data) ? get_class($data) : gettype($data))
+            ));
+        }
+
+        $feed = new Feed();
+
+        foreach ($data as $key => $value) {
+            // Setters
+            $key    = static::convertKey($key);
+            $method = 'set' . $key;
+            if (method_exists($feed, $method)) {
+                switch ($method) {
+                    case 'setfeedlink':
+                        if (!is_array($value)) {
+                            // Need an array
+                            break;
+                        }
+                        if (!array_key_exists('link', $value) || !array_key_exists('type', $value)) {
+                            // Need both keys to set this correctly
+                            break;
+                        }
+                        $feed->setFeedLink($value['link'], $value['type']);
+                        break;
+                    default:
+                        $feed->$method($value);
+                        break;
+                }
+                continue;
+            }
+
+            // Entries
+            if ('entries' == $key) {
+                static::createEntries($value, $feed);
+                continue;
+            }
+        }
+
+        return $feed;
+    }
+
+    /**
+     * Normalize a key
+     *
+     * @param  string $key
+     * @return string
+     */
+    protected static function convertKey($key)
+    {
+        $key = str_replace('_', '', strtolower($key));
+        return $key;
+    }
+
+    /**
+     * Create and attach entries to a feed
+     *
+     * @param  array|Traversable $entries
+     * @param  Feed $feed
+     * @throws Exception\InvalidArgumentException
+     * @return void
+     */
+    protected static function createEntries($entries, Feed $feed)
+    {
+        if (!is_array($entries) && !$entries instanceof Traversable) {
+            throw new Exception\InvalidArgumentException(sprintf(
+                '%s::factory expects the "entries" value to be an array or Traversable; received "%s"',
+                get_called_class(),
+                (is_object($entries) ? get_class($entries) : gettype($entries))
+            ));
+        }
+
+        foreach ($entries as $data) {
+            if (!is_array($data) && !$data instanceof Traversable && !$data instanceof Entry) {
+                throw new Exception\InvalidArgumentException(sprintf(
+                    '%s expects an array, Traversable, or Zend\Feed\Writer\Entry argument; received "%s"',
+                    __METHOD__,
+                    (is_object($data) ? get_class($data) : gettype($data))
+                ));
+            }
+
+            // Use case 1: Entry item
+            if ($data instanceof Entry) {
+                $feed->addEntry($data);
+                continue;
+            }
+
+            // Use case 2: iterate item and populate entry
+            $entry = $feed->createEntry();
+            foreach ($data as $key => $value) {
+                $key    = static::convertKey($key);
+                $method = 'set' . $key;
+                if (!method_exists($entry, $method)) {
+                    continue;
+                }
+                $entry->$method($value);
+            }
+            $feed->addEntry($entry);
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/AbstractRenderer.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/AbstractRenderer.php
new file mode 100644
index 000000000000..f981f49a0136
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/AbstractRenderer.php
@@ -0,0 +1,233 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Renderer;
+
+use DOMDocument;
+use DOMElement;
+use Zend\Feed\Writer;
+
+/**
+*/
+class AbstractRenderer
+{
+    /**
+     * Extensions
+     * @var array
+     */
+    protected $extensions = array();
+
+    /**
+     * @var Writer\AbstractFeed
+     */
+    protected $container = null;
+
+    /**
+     * @var DOMDocument
+     */
+    protected $dom = null;
+
+    /**
+     * @var bool
+     */
+    protected $ignoreExceptions = false;
+
+    /**
+     * @var array
+     */
+    protected $exceptions = array();
+
+    /**
+     * Encoding of all text values
+     *
+     * @var string
+     */
+    protected $encoding = 'UTF-8';
+
+    /**
+     * Holds the value "atom" or "rss" depending on the feed type set when
+     * when last exported.
+     *
+     * @var string
+     */
+    protected $type = null;
+
+    /**
+     * @var DOMElement
+     */
+    protected $rootElement = null;
+
+    /**
+     * Constructor
+     *
+     * @param Writer\AbstractFeed $container
+     */
+    public function __construct($container)
+    {
+        $this->container = $container;
+        $this->setType($container->getType());
+        $this->_loadExtensions();
+    }
+
+    /**
+     * Save XML to string
+     *
+     * @return string
+     */
+    public function saveXml()
+    {
+        return $this->getDomDocument()->saveXml();
+    }
+
+    /**
+     * Get DOM document
+     *
+     * @return DOMDocument
+     */
+    public function getDomDocument()
+    {
+        return $this->dom;
+    }
+
+    /**
+     * Get document element from DOM
+     *
+     * @return DOMElement
+     */
+    public function getElement()
+    {
+        return $this->getDomDocument()->documentElement;
+    }
+
+    /**
+     * Get data container of items being rendered
+     *
+     * @return Writer\AbstractFeed
+     */
+    public function getDataContainer()
+    {
+        return $this->container;
+    }
+
+    /**
+     * Set feed encoding
+     *
+     * @param  string $enc
+     * @return AbstractRenderer
+     */
+    public function setEncoding($enc)
+    {
+        $this->encoding = $enc;
+        return $this;
+    }
+
+    /**
+     * Get feed encoding
+     *
+     * @return string
+     */
+    public function getEncoding()
+    {
+        return $this->encoding;
+    }
+
+    /**
+     * Indicate whether or not to ignore exceptions
+     *
+     * @param  bool $bool
+     * @return AbstractRenderer
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    public function ignoreExceptions($bool = true)
+    {
+        if (!is_bool($bool)) {
+            throw new Writer\Exception\InvalidArgumentException('Invalid parameter: $bool. Should be TRUE or FALSE (defaults to TRUE if null)');
+        }
+        $this->ignoreExceptions = $bool;
+        return $this;
+    }
+
+    /**
+     * Get exception list
+     *
+     * @return array
+     */
+    public function getExceptions()
+    {
+        return $this->exceptions;
+    }
+
+    /**
+     * Set the current feed type being exported to "rss" or "atom". This allows
+     * other objects to gracefully choose whether to execute or not, depending
+     * on their appropriateness for the current type, e.g. renderers.
+     *
+     * @param string $type
+     */
+    public function setType($type)
+    {
+        $this->type = $type;
+    }
+
+    /**
+     * Retrieve the current or last feed type exported.
+     *
+     * @return string Value will be "rss" or "atom"
+     */
+    public function getType()
+    {
+        return $this->type;
+    }
+
+    /**
+     * Sets the absolute root element for the XML feed being generated. This
+     * helps simplify the appending of namespace declarations, but also ensures
+     * namespaces are added to the root element - not scattered across the entire
+     * XML file - may assist namespace unsafe parsers and looks pretty ;).
+     *
+     * @param DOMElement $root
+     */
+    public function setRootElement(DOMElement $root)
+    {
+        $this->rootElement = $root;
+    }
+
+    /**
+     * Retrieve the absolute root element for the XML feed being generated.
+     *
+     * @return DOMElement
+     */
+    public function getRootElement()
+    {
+        return $this->rootElement;
+    }
+
+    /**
+     * Load extensions from Zend\Feed\Writer\Writer
+     *
+     * @return void
+     */
+    protected function _loadExtensions()
+    {
+        Writer\Writer::registerCoreExtensions();
+        $manager = Writer\Writer::getExtensionManager();
+        $all = Writer\Writer::getExtensions();
+        if (stripos(get_class($this), 'entry')) {
+            $exts = $all['entryRenderer'];
+        } else {
+            $exts = $all['feedRenderer'];
+        }
+        foreach ($exts as $extension) {
+            $plugin = $manager->get($extension);
+            $plugin->setDataContainer($this->getDataContainer());
+            $plugin->setEncoding($this->getEncoding());
+            $this->extensions[$extension] = $plugin;
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Entry/Atom.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Entry/Atom.php
new file mode 100644
index 000000000000..1758f4ff68e7
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Entry/Atom.php
@@ -0,0 +1,427 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Renderer\Entry;
+
+use DateTime;
+use DOMDocument;
+use DOMElement;
+use Zend\Feed\Uri;
+use Zend\Feed\Writer;
+use Zend\Feed\Writer\Renderer;
+use Zend\Validator;
+
+class Atom extends Renderer\AbstractRenderer implements Renderer\RendererInterface
+{
+    /**
+     * Constructor
+     *
+     * @param  Writer\Entry $container
+     */
+    public function __construct (Writer\Entry $container)
+    {
+        parent::__construct($container);
+    }
+
+    /**
+     * Render atom entry
+     *
+     * @return Atom
+     */
+    public function render()
+    {
+        $this->dom = new DOMDocument('1.0', $this->container->getEncoding());
+        $this->dom->formatOutput = true;
+        $entry = $this->dom->createElementNS(Writer\Writer::NAMESPACE_ATOM_10, 'entry');
+        $this->dom->appendChild($entry);
+
+        $this->_setSource($this->dom, $entry);
+        $this->_setTitle($this->dom, $entry);
+        $this->_setDescription($this->dom, $entry);
+        $this->_setDateCreated($this->dom, $entry);
+        $this->_setDateModified($this->dom, $entry);
+        $this->_setLink($this->dom, $entry);
+        $this->_setId($this->dom, $entry);
+        $this->_setAuthors($this->dom, $entry);
+        $this->_setEnclosure($this->dom, $entry);
+        $this->_setContent($this->dom, $entry);
+        $this->_setCategories($this->dom, $entry);
+
+        foreach ($this->extensions as $ext) {
+            $ext->setType($this->getType());
+            $ext->setRootElement($this->getRootElement());
+            $ext->setDOMDocument($this->getDOMDocument(), $entry);
+            $ext->render();
+        }
+
+        return $this;
+    }
+
+    /**
+     * Set entry title
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    protected function _setTitle(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getTitle()) {
+            $message = 'Atom 1.0 entry elements MUST contain exactly one'
+            . ' atom:title element but a title has not been set';
+            $exception = new Writer\Exception\InvalidArgumentException($message);
+            if (!$this->ignoreExceptions) {
+                throw $exception;
+            } else {
+                $this->exceptions[] = $exception;
+                return;
+            }
+        }
+        $title = $dom->createElement('title');
+        $root->appendChild($title);
+        $title->setAttribute('type', 'html');
+        $cdata = $dom->createCDATASection($this->getDataContainer()->getTitle());
+        $title->appendChild($cdata);
+    }
+
+    /**
+     * Set entry description
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setDescription(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getDescription()) {
+            return; // unless src content or base64
+        }
+        $subtitle = $dom->createElement('summary');
+        $root->appendChild($subtitle);
+        $subtitle->setAttribute('type', 'html');
+        $cdata = $dom->createCDATASection(
+            $this->getDataContainer()->getDescription()
+        );
+        $subtitle->appendChild($cdata);
+    }
+
+    /**
+     * Set date entry was modified
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    protected function _setDateModified(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getDateModified()) {
+            $message = 'Atom 1.0 entry elements MUST contain exactly one'
+            . ' atom:updated element but a modification date has not been set';
+            $exception = new Writer\Exception\InvalidArgumentException($message);
+            if (!$this->ignoreExceptions) {
+                throw $exception;
+            } else {
+                $this->exceptions[] = $exception;
+                return;
+            }
+        }
+
+        $updated = $dom->createElement('updated');
+        $root->appendChild($updated);
+        $text = $dom->createTextNode(
+            $this->getDataContainer()->getDateModified()->format(DateTime::ISO8601)
+        );
+        $updated->appendChild($text);
+    }
+
+    /**
+     * Set date entry was created
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setDateCreated(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getDateCreated()) {
+            return;
+        }
+        $el = $dom->createElement('published');
+        $root->appendChild($el);
+        $text = $dom->createTextNode(
+            $this->getDataContainer()->getDateCreated()->format(DateTime::ISO8601)
+        );
+        $el->appendChild($text);
+    }
+
+    /**
+     * Set entry authors
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setAuthors(DOMDocument $dom, DOMElement $root)
+    {
+        $authors = $this->container->getAuthors();
+        if ((!$authors || empty($authors))) {
+            /**
+             * This will actually trigger an Exception at the feed level if
+             * a feed level author is not set.
+             */
+            return;
+        }
+        foreach ($authors as $data) {
+            $author = $this->dom->createElement('author');
+            $name = $this->dom->createElement('name');
+            $author->appendChild($name);
+            $root->appendChild($author);
+            $text = $dom->createTextNode($data['name']);
+            $name->appendChild($text);
+            if (array_key_exists('email', $data)) {
+                $email = $this->dom->createElement('email');
+                $author->appendChild($email);
+                $text = $dom->createTextNode($data['email']);
+                $email->appendChild($text);
+            }
+            if (array_key_exists('uri', $data)) {
+                $uri = $this->dom->createElement('uri');
+                $author->appendChild($uri);
+                $text = $dom->createTextNode($data['uri']);
+                $uri->appendChild($text);
+            }
+        }
+    }
+
+    /**
+     * Set entry enclosure
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setEnclosure(DOMDocument $dom, DOMElement $root)
+    {
+        $data = $this->container->getEnclosure();
+        if ((!$data || empty($data))) {
+            return;
+        }
+        $enclosure = $this->dom->createElement('link');
+        $enclosure->setAttribute('rel', 'enclosure');
+        if (isset($data['type'])) {
+            $enclosure->setAttribute('type', $data['type']);
+        }
+        if (isset($data['length'])) {
+            $enclosure->setAttribute('length', $data['length']);
+        }
+        $enclosure->setAttribute('href', $data['uri']);
+        $root->appendChild($enclosure);
+    }
+
+    protected function _setLink(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getLink()) {
+            return;
+        }
+        $link = $dom->createElement('link');
+        $root->appendChild($link);
+        $link->setAttribute('rel', 'alternate');
+        $link->setAttribute('type', 'text/html');
+        $link->setAttribute('href', $this->getDataContainer()->getLink());
+    }
+
+    /**
+     * Set entry identifier
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    protected function _setId(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getId()
+        && !$this->getDataContainer()->getLink()) {
+            $message = 'Atom 1.0 entry elements MUST contain exactly one '
+            . 'atom:id element, or as an alternative, we can use the same '
+            . 'value as atom:link however neither a suitable link nor an '
+            . 'id have been set';
+            $exception = new Writer\Exception\InvalidArgumentException($message);
+            if (!$this->ignoreExceptions) {
+                throw $exception;
+            } else {
+                $this->exceptions[] = $exception;
+                return;
+            }
+        }
+
+        if (!$this->getDataContainer()->getId()) {
+            $this->getDataContainer()->setId(
+                $this->getDataContainer()->getLink());
+        }
+        if (!Uri::factory($this->getDataContainer()->getId())->isValid()
+            && !preg_match(
+                "#^urn:[a-zA-Z0-9][a-zA-Z0-9\-]{1,31}:([a-zA-Z0-9\(\)\+\,\.\:\=\@\;\$\_\!\*\-]|%[0-9a-fA-F]{2})*#",
+                $this->getDataContainer()->getId())
+            && !$this->_validateTagUri($this->getDataContainer()->getId())
+        ) {
+            throw new Writer\Exception\InvalidArgumentException('Atom 1.0 IDs must be a valid URI/IRI');
+        }
+        $id = $dom->createElement('id');
+        $root->appendChild($id);
+        $text = $dom->createTextNode($this->getDataContainer()->getId());
+        $id->appendChild($text);
+    }
+
+    /**
+     * Validate a URI using the tag scheme (RFC 4151)
+     *
+     * @param string $id
+     * @return bool
+     */
+    protected function _validateTagUri($id)
+    {
+        if (preg_match('/^tag:(?P<name>.*),(?P<date>\d{4}-?\d{0,2}-?\d{0,2}):(?P<specific>.*)(.*:)*$/', $id, $matches)) {
+            $dvalid = false;
+            $nvalid = false;
+            $date = $matches['date'];
+            $d6 = strtotime($date);
+            if ((strlen($date) == 4) && $date <= date('Y')) {
+                $dvalid = true;
+            } elseif ((strlen($date) == 7) && ($d6 < strtotime("now"))) {
+                $dvalid = true;
+            } elseif ((strlen($date) == 10) && ($d6 < strtotime("now"))) {
+                $dvalid = true;
+            }
+            $validator = new Validator\EmailAddress;
+            if ($validator->isValid($matches['name'])) {
+                $nvalid = true;
+            } else {
+                $nvalid = $validator->isValid('info@' . $matches['name']);
+            }
+            return $dvalid && $nvalid;
+
+        }
+        return false;
+    }
+
+    /**
+     * Set entry content
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    protected function _setContent(DOMDocument $dom, DOMElement $root)
+    {
+        $content = $this->getDataContainer()->getContent();
+        if (!$content && !$this->getDataContainer()->getLink()) {
+            $message = 'Atom 1.0 entry elements MUST contain exactly one '
+            . 'atom:content element, or as an alternative, at least one link '
+            . 'with a rel attribute of "alternate" to indicate an alternate '
+            . 'method to consume the content.';
+            $exception = new Writer\Exception\InvalidArgumentException($message);
+            if (!$this->ignoreExceptions) {
+                throw $exception;
+            } else {
+                $this->exceptions[] = $exception;
+                return;
+            }
+        }
+        if (!$content) {
+            return;
+        }
+        $element = $dom->createElement('content');
+        $element->setAttribute('type', 'xhtml');
+        $xhtmlElement = $this->_loadXhtml($content);
+        $xhtml = $dom->importNode($xhtmlElement, true);
+        $element->appendChild($xhtml);
+        $root->appendChild($element);
+    }
+
+    /**
+     * Load a HTML string and attempt to normalise to XML
+     */
+    protected function _loadXhtml($content)
+    {
+        $xhtml = '';
+        if (class_exists('tidy', false)) {
+            $tidy = new \tidy;
+            $config = array(
+                'output-xhtml' => true,
+                'show-body-only' => true,
+                'quote-nbsp' => false
+            );
+            $encoding = str_replace('-', '', $this->getEncoding());
+            $tidy->parseString($content, $config, $encoding);
+            $tidy->cleanRepair();
+            $xhtml = (string) $tidy;
+        } else {
+            $xhtml = $content;
+        }
+        $xhtml = preg_replace(array(
+            "/(<[\/]?)([a-zA-Z]+)/"
+        ), '$1xhtml:$2', $xhtml);
+        $dom = new DOMDocument('1.0', $this->getEncoding());
+        $dom->loadXML('<xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml">'
+            . $xhtml . '</xhtml:div>');
+        return $dom->documentElement;
+    }
+
+    /**
+     * Set entry categories
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setCategories(DOMDocument $dom, DOMElement $root)
+    {
+        $categories = $this->getDataContainer()->getCategories();
+        if (!$categories) {
+            return;
+        }
+        foreach ($categories as $cat) {
+            $category = $dom->createElement('category');
+            $category->setAttribute('term', $cat['term']);
+            if (isset($cat['label'])) {
+                $category->setAttribute('label', $cat['label']);
+            } else {
+                $category->setAttribute('label', $cat['term']);
+            }
+            if (isset($cat['scheme'])) {
+                $category->setAttribute('scheme', $cat['scheme']);
+            }
+            $root->appendChild($category);
+        }
+    }
+
+    /**
+     * Append Source element (Atom 1.0 Feed Metadata)
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setSource(DOMDocument $dom, DOMElement $root)
+    {
+        $source = $this->getDataContainer()->getSource();
+        if (!$source) {
+            return;
+        }
+        $renderer = new Renderer\Feed\AtomSource($source);
+        $renderer->setType($this->getType());
+        $element = $renderer->render()->getElement();
+        $imported = $dom->importNode($element, true);
+        $root->appendChild($imported);
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Entry/Atom/Deleted.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Entry/Atom/Deleted.php
new file mode 100644
index 000000000000..679b6c48f42f
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Entry/Atom/Deleted.php
@@ -0,0 +1,102 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Renderer\Entry\Atom;
+
+use DateTime;
+use DOMDocument;
+use DOMElement;
+
+class Deleted
+    extends \Zend\Feed\Writer\Renderer\AbstractRenderer
+    implements \Zend\Feed\Writer\Renderer\RendererInterface
+{
+    /**
+     * Constructor
+     *
+     * @param  \Zend\Feed\Writer\Deleted $container
+     */
+    public function __construct (\Zend\Feed\Writer\Deleted $container)
+    {
+        parent::__construct($container);
+    }
+
+    /**
+     * Render atom entry
+     *
+     * @return \Zend\Feed\Writer\Renderer\Entry\Atom
+     */
+    public function render()
+    {
+        $this->dom = new DOMDocument('1.0', $this->container->getEncoding());
+        $this->dom->formatOutput = true;
+        $entry = $this->dom->createElement('at:deleted-entry');
+        $this->dom->appendChild($entry);
+
+        $entry->setAttribute('ref', $this->container->getReference());
+        $entry->setAttribute('when', $this->container->getWhen()->format(DateTime::ISO8601));
+
+        $this->_setBy($this->dom, $entry);
+        $this->_setComment($this->dom, $entry);
+
+        return $this;
+    }
+
+    /**
+     * Set tombstone comment
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setComment(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getComment()) {
+            return;
+        }
+        $c = $dom->createElement('at:comment');
+        $root->appendChild($c);
+        $c->setAttribute('type', 'html');
+        $cdata = $dom->createCDATASection($this->getDataContainer()->getComment());
+        $c->appendChild($cdata);
+    }
+
+    /**
+     * Set entry authors
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setBy(DOMDocument $dom, DOMElement $root)
+    {
+        $data = $this->container->getBy();
+        if ((!$data || empty($data))) {
+            return;
+        }
+        $author = $this->dom->createElement('at:by');
+        $name = $this->dom->createElement('name');
+        $author->appendChild($name);
+        $root->appendChild($author);
+        $text = $dom->createTextNode($data['name']);
+        $name->appendChild($text);
+        if (array_key_exists('email', $data)) {
+            $email = $this->dom->createElement('email');
+            $author->appendChild($email);
+            $text = $dom->createTextNode($data['email']);
+            $email->appendChild($text);
+        }
+        if (array_key_exists('uri', $data)) {
+            $uri = $this->dom->createElement('uri');
+            $author->appendChild($uri);
+            $text = $dom->createTextNode($data['uri']);
+            $uri->appendChild($text);
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Entry/AtomDeleted.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Entry/AtomDeleted.php
new file mode 100644
index 000000000000..fd12eef58680
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Entry/AtomDeleted.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Renderer\Entry;
+
+use DateTime;
+use DOMDocument;
+use DOMElement;
+use Zend\Feed\Writer;
+use Zend\Feed\Writer\Renderer;
+
+/**
+*/
+class AtomDeleted extends Renderer\AbstractRenderer implements Renderer\RendererInterface
+{
+    /**
+     * Constructor
+     *
+     * @param  Writer\Deleted $container
+     */
+    public function __construct (Writer\Deleted $container)
+    {
+        parent::__construct($container);
+    }
+
+    /**
+     * Render atom entry
+     *
+     * @return \Zend\Feed\Writer\Renderer\Entry\Atom
+     */
+    public function render()
+    {
+        $this->dom = new DOMDocument('1.0', $this->container->getEncoding());
+        $this->dom->formatOutput = true;
+        $entry = $this->dom->createElement('at:deleted-entry');
+        $this->dom->appendChild($entry);
+
+        $entry->setAttribute('ref', $this->container->getReference());
+        $entry->setAttribute('when', $this->container->getWhen()->format(DateTime::ISO8601));
+
+        $this->_setBy($this->dom, $entry);
+        $this->_setComment($this->dom, $entry);
+
+        return $this;
+    }
+
+    /**
+     * Set tombstone comment
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setComment(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getComment()) {
+            return;
+        }
+        $c = $dom->createElement('at:comment');
+        $root->appendChild($c);
+        $c->setAttribute('type', 'html');
+        $cdata = $dom->createCDATASection($this->getDataContainer()->getComment());
+        $c->appendChild($cdata);
+    }
+
+    /**
+     * Set entry authors
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setBy(DOMDocument $dom, DOMElement $root)
+    {
+        $data = $this->container->getBy();
+        if ((!$data || empty($data))) {
+            return;
+        }
+        $author = $this->dom->createElement('at:by');
+        $name = $this->dom->createElement('name');
+        $author->appendChild($name);
+        $root->appendChild($author);
+        $text = $dom->createTextNode($data['name']);
+        $name->appendChild($text);
+        if (array_key_exists('email', $data)) {
+            $email = $this->dom->createElement('email');
+            $author->appendChild($email);
+            $text = $dom->createTextNode($data['email']);
+            $email->appendChild($text);
+        }
+        if (array_key_exists('uri', $data)) {
+            $uri = $this->dom->createElement('uri');
+            $author->appendChild($uri);
+            $text = $dom->createTextNode($data['uri']);
+            $uri->appendChild($text);
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Entry/Rss.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Entry/Rss.php
new file mode 100644
index 000000000000..8d352c9c190e
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Entry/Rss.php
@@ -0,0 +1,329 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Renderer\Entry;
+
+use DateTime;
+use DOMDocument;
+use DOMElement;
+use Zend\Feed\Uri;
+use Zend\Feed\Writer;
+use Zend\Feed\Writer\Renderer;
+
+/**
+*/
+class Rss extends Renderer\AbstractRenderer implements Renderer\RendererInterface
+{
+    /**
+     * Constructor
+     *
+     * @param  Writer\Entry $container
+     */
+    public function __construct (Writer\Entry $container)
+    {
+        parent::__construct($container);
+    }
+
+    /**
+     * Render RSS entry
+     *
+     * @return Rss
+     */
+    public function render()
+    {
+        $this->dom = new DOMDocument('1.0', $this->container->getEncoding());
+        $this->dom->formatOutput = true;
+        $this->dom->substituteEntities = false;
+        $entry = $this->dom->createElement('item');
+        $this->dom->appendChild($entry);
+
+        $this->_setTitle($this->dom, $entry);
+        $this->_setDescription($this->dom, $entry);
+        $this->_setDateCreated($this->dom, $entry);
+        $this->_setDateModified($this->dom, $entry);
+        $this->_setLink($this->dom, $entry);
+        $this->_setId($this->dom, $entry);
+        $this->_setAuthors($this->dom, $entry);
+        $this->_setEnclosure($this->dom, $entry);
+        $this->_setCommentLink($this->dom, $entry);
+        $this->_setCategories($this->dom, $entry);
+        foreach ($this->extensions as $ext) {
+            $ext->setType($this->getType());
+            $ext->setRootElement($this->getRootElement());
+            $ext->setDOMDocument($this->getDOMDocument(), $entry);
+            $ext->render();
+        }
+
+        return $this;
+    }
+
+    /**
+     * Set entry title
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    protected function _setTitle(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getDescription()
+        && !$this->getDataContainer()->getTitle()) {
+            $message = 'RSS 2.0 entry elements SHOULD contain exactly one'
+            . ' title element but a title has not been set. In addition, there'
+            . ' is no description as required in the absence of a title.';
+            $exception = new Writer\Exception\InvalidArgumentException($message);
+            if (!$this->ignoreExceptions) {
+                throw $exception;
+            } else {
+                $this->exceptions[] = $exception;
+                return;
+            }
+        }
+        $title = $dom->createElement('title');
+        $root->appendChild($title);
+        $text = $dom->createTextNode($this->getDataContainer()->getTitle());
+        $title->appendChild($text);
+    }
+
+    /**
+     * Set entry description
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    protected function _setDescription(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getDescription()
+        && !$this->getDataContainer()->getTitle()) {
+            $message = 'RSS 2.0 entry elements SHOULD contain exactly one'
+            . ' description element but a description has not been set. In'
+            . ' addition, there is no title element as required in the absence'
+            . ' of a description.';
+            $exception = new Writer\Exception\InvalidArgumentException($message);
+            if (!$this->ignoreExceptions) {
+                throw $exception;
+            } else {
+                $this->exceptions[] = $exception;
+                return;
+            }
+        }
+        if (!$this->getDataContainer()->getDescription()) {
+            return;
+        }
+        $subtitle = $dom->createElement('description');
+        $root->appendChild($subtitle);
+        $text = $dom->createCDATASection($this->getDataContainer()->getDescription());
+        $subtitle->appendChild($text);
+    }
+
+    /**
+     * Set date entry was last modified
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setDateModified(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getDateModified()) {
+            return;
+        }
+
+        $updated = $dom->createElement('pubDate');
+        $root->appendChild($updated);
+        $text = $dom->createTextNode(
+            $this->getDataContainer()->getDateModified()->format(DateTime::RSS)
+        );
+        $updated->appendChild($text);
+    }
+
+    /**
+     * Set date entry was created
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setDateCreated(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getDateCreated()) {
+            return;
+        }
+        if (!$this->getDataContainer()->getDateModified()) {
+            $this->getDataContainer()->setDateModified(
+                $this->getDataContainer()->getDateCreated()
+            );
+        }
+    }
+
+    /**
+     * Set entry authors
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setAuthors(DOMDocument $dom, DOMElement $root)
+    {
+        $authors = $this->container->getAuthors();
+        if ((!$authors || empty($authors))) {
+            return;
+        }
+        foreach ($authors as $data) {
+            $author = $this->dom->createElement('author');
+            $name = $data['name'];
+            if (array_key_exists('email', $data)) {
+                $name = $data['email'] . ' (' . $data['name'] . ')';
+            }
+            $text = $dom->createTextNode($name);
+            $author->appendChild($text);
+            $root->appendChild($author);
+        }
+    }
+
+    /**
+     * Set entry enclosure
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    protected function _setEnclosure(DOMDocument $dom, DOMElement $root)
+    {
+        $data = $this->container->getEnclosure();
+        if ((!$data || empty($data))) {
+            return;
+        }
+        if (!isset($data['type'])) {
+            $exception = new Writer\Exception\InvalidArgumentException('Enclosure "type" is not set');
+            if (!$this->ignoreExceptions) {
+                throw $exception;
+            } else {
+                $this->exceptions[] = $exception;
+                return;
+            }
+        }
+        if (!isset($data['length'])) {
+            $exception = new Writer\Exception\InvalidArgumentException('Enclosure "length" is not set');
+            if (!$this->ignoreExceptions) {
+                throw $exception;
+            } else {
+                $this->exceptions[] = $exception;
+                return;
+            }
+        }
+        if (isset($data['length']) && (int) $data['length'] <= 0) {
+            $exception = new Writer\Exception\InvalidArgumentException('Enclosure "length" must be an integer'
+            . ' indicating the content\'s length in bytes');
+            if (!$this->ignoreExceptions) {
+                throw $exception;
+            } else {
+                $this->exceptions[] = $exception;
+                return;
+            }
+        }
+        $enclosure = $this->dom->createElement('enclosure');
+        $enclosure->setAttribute('type', $data['type']);
+        $enclosure->setAttribute('length', $data['length']);
+        $enclosure->setAttribute('url', $data['uri']);
+        $root->appendChild($enclosure);
+    }
+
+    /**
+     * Set link to entry
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setLink(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getLink()) {
+            return;
+        }
+        $link = $dom->createElement('link');
+        $root->appendChild($link);
+        $text = $dom->createTextNode($this->getDataContainer()->getLink());
+        $link->appendChild($text);
+    }
+
+    /**
+     * Set entry identifier
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setId(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getId()
+        && !$this->getDataContainer()->getLink()) {
+            return;
+        }
+
+        $id = $dom->createElement('guid');
+        $root->appendChild($id);
+        if (!$this->getDataContainer()->getId()) {
+            $this->getDataContainer()->setId(
+                $this->getDataContainer()->getLink());
+        }
+        $text = $dom->createTextNode($this->getDataContainer()->getId());
+        $id->appendChild($text);
+        if (!Uri::factory($this->getDataContainer()->getId())->isValid()) {
+            $id->setAttribute('isPermaLink', 'false');
+        }
+    }
+
+    /**
+     * Set link to entry comments
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setCommentLink(DOMDocument $dom, DOMElement $root)
+    {
+        $link = $this->getDataContainer()->getCommentLink();
+        if (!$link) {
+            return;
+        }
+        $clink = $this->dom->createElement('comments');
+        $text = $dom->createTextNode($link);
+        $clink->appendChild($text);
+        $root->appendChild($clink);
+    }
+
+    /**
+     * Set entry categories
+     *
+     * @param DOMDocument $dom
+     * @param DOMElement $root
+     * @return void
+     */
+    protected function _setCategories(DOMDocument $dom, DOMElement $root)
+    {
+        $categories = $this->getDataContainer()->getCategories();
+        if (!$categories) {
+            return;
+        }
+        foreach ($categories as $cat) {
+            $category = $dom->createElement('category');
+            if (isset($cat['scheme'])) {
+                $category->setAttribute('domain', $cat['scheme']);
+            }
+            $text = $dom->createCDATASection($cat['term']);
+            $category->appendChild($text);
+            $root->appendChild($category);
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Feed/AbstractAtom.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Feed/AbstractAtom.php
new file mode 100644
index 000000000000..2ff11129ac49
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Feed/AbstractAtom.php
@@ -0,0 +1,403 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Renderer\Feed;
+
+use DateTime;
+use DOMDocument;
+use DOMElement;
+use Zend\Feed\Writer;
+use Zend\Feed\Writer\Renderer;
+use Zend\Feed\Writer\Version;
+
+/**
+*/
+class AbstractAtom extends Renderer\AbstractRenderer
+{
+    /**
+     * Constructor
+     *
+     * @param  Writer\AbstractFeed $container
+     */
+    public function __construct($container)
+    {
+        parent::__construct($container);
+    }
+
+    /**
+     * Set feed language
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setLanguage(DOMDocument $dom, DOMElement $root)
+    {
+        if ($this->getDataContainer()->getLanguage()) {
+            $root->setAttribute('xml:lang', $this->getDataContainer()
+                ->getLanguage());
+        }
+    }
+
+    /**
+     * Set feed title
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    protected function _setTitle(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getTitle()) {
+            $message = 'Atom 1.0 feed elements MUST contain exactly one'
+            . ' atom:title element but a title has not been set';
+            $exception = new Writer\Exception\InvalidArgumentException($message);
+            if (!$this->ignoreExceptions) {
+                throw $exception;
+            } else {
+                $this->exceptions[] = $exception;
+                return;
+            }
+        }
+
+        $title = $dom->createElement('title');
+        $root->appendChild($title);
+        $title->setAttribute('type', 'text');
+        $text = $dom->createTextNode($this->getDataContainer()->getTitle());
+        $title->appendChild($text);
+    }
+
+    /**
+     * Set feed description
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setDescription(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getDescription()) {
+            return;
+        }
+        $subtitle = $dom->createElement('subtitle');
+        $root->appendChild($subtitle);
+        $subtitle->setAttribute('type', 'text');
+        $text = $dom->createTextNode($this->getDataContainer()->getDescription());
+        $subtitle->appendChild($text);
+    }
+
+    /**
+     * Set date feed was last modified
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    protected function _setDateModified(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getDateModified()) {
+            $message = 'Atom 1.0 feed elements MUST contain exactly one'
+            . ' atom:updated element but a modification date has not been set';
+            $exception = new Writer\Exception\InvalidArgumentException($message);
+            if (!$this->ignoreExceptions) {
+                throw $exception;
+            } else {
+                $this->exceptions[] = $exception;
+                return;
+            }
+        }
+
+        $updated = $dom->createElement('updated');
+        $root->appendChild($updated);
+        $text = $dom->createTextNode(
+            $this->getDataContainer()->getDateModified()->format(DateTime::ISO8601)
+        );
+        $updated->appendChild($text);
+    }
+
+    /**
+     * Set feed generator string
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setGenerator(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getGenerator()) {
+            $this->getDataContainer()->setGenerator('Zend_Feed_Writer',
+                Version::VERSION, 'http://framework.zend.com');
+        }
+
+        $gdata = $this->getDataContainer()->getGenerator();
+        $generator = $dom->createElement('generator');
+        $root->appendChild($generator);
+        $text = $dom->createTextNode($gdata['name']);
+        $generator->appendChild($text);
+        if (array_key_exists('uri', $gdata)) {
+            $generator->setAttribute('uri', $gdata['uri']);
+        }
+        if (array_key_exists('version', $gdata)) {
+            $generator->setAttribute('version', $gdata['version']);
+        }
+    }
+
+    /**
+     * Set link to feed
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setLink(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getLink()) {
+            return;
+        }
+        $link = $dom->createElement('link');
+        $root->appendChild($link);
+        $link->setAttribute('rel', 'alternate');
+        $link->setAttribute('type', 'text/html');
+        $link->setAttribute('href', $this->getDataContainer()->getLink());
+    }
+
+    /**
+     * Set feed links
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    protected function _setFeedLinks(DOMDocument $dom, DOMElement $root)
+    {
+        $flinks = $this->getDataContainer()->getFeedLinks();
+        if (!$flinks || !array_key_exists('atom', $flinks)) {
+            $message = 'Atom 1.0 feed elements SHOULD contain one atom:link '
+            . 'element with a rel attribute value of "self".  This is the '
+            . 'preferred URI for retrieving Atom Feed Documents representing '
+            . 'this Atom feed but a feed link has not been set';
+            $exception = new Writer\Exception\InvalidArgumentException($message);
+            if (!$this->ignoreExceptions) {
+                throw $exception;
+            } else {
+                $this->exceptions[] = $exception;
+                return;
+            }
+        }
+
+        foreach ($flinks as $type => $href) {
+            $mime = 'application/' . strtolower($type) . '+xml';
+            $flink = $dom->createElement('link');
+            $root->appendChild($flink);
+            $flink->setAttribute('rel', 'self');
+            $flink->setAttribute('type', $mime);
+            $flink->setAttribute('href', $href);
+        }
+    }
+
+    /**
+     * Set feed authors
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setAuthors(DOMDocument $dom, DOMElement $root)
+    {
+        $authors = $this->container->getAuthors();
+        if (!$authors || empty($authors)) {
+            /**
+             * Technically we should defer an exception until we can check
+             * that all entries contain an author. If any entry is missing
+             * an author, then a missing feed author element is invalid
+             */
+            return;
+        }
+        foreach ($authors as $data) {
+            $author = $this->dom->createElement('author');
+            $name = $this->dom->createElement('name');
+            $author->appendChild($name);
+            $root->appendChild($author);
+            $text = $dom->createTextNode($data['name']);
+            $name->appendChild($text);
+            if (array_key_exists('email', $data)) {
+                $email = $this->dom->createElement('email');
+                $author->appendChild($email);
+                $text = $dom->createTextNode($data['email']);
+                $email->appendChild($text);
+            }
+            if (array_key_exists('uri', $data)) {
+                $uri = $this->dom->createElement('uri');
+                $author->appendChild($uri);
+                $text = $dom->createTextNode($data['uri']);
+                $uri->appendChild($text);
+            }
+        }
+    }
+
+    /**
+     * Set feed identifier
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    protected function _setId(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getId()
+        && !$this->getDataContainer()->getLink()) {
+            $message = 'Atom 1.0 feed elements MUST contain exactly one '
+            . 'atom:id element, or as an alternative, we can use the same '
+            . 'value as atom:link however neither a suitable link nor an '
+            . 'id have been set';
+            $exception = new Writer\Exception\InvalidArgumentException($message);
+            if (!$this->ignoreExceptions) {
+                throw $exception;
+            } else {
+                $this->exceptions[] = $exception;
+                return;
+            }
+        }
+
+        if (!$this->getDataContainer()->getId()) {
+            $this->getDataContainer()->setId(
+                $this->getDataContainer()->getLink());
+        }
+        $id = $dom->createElement('id');
+        $root->appendChild($id);
+        $text = $dom->createTextNode($this->getDataContainer()->getId());
+        $id->appendChild($text);
+    }
+
+    /**
+     * Set feed copyright
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setCopyright(DOMDocument $dom, DOMElement $root)
+    {
+        $copyright = $this->getDataContainer()->getCopyright();
+        if (!$copyright) {
+            return;
+        }
+        $copy = $dom->createElement('rights');
+        $root->appendChild($copy);
+        $text = $dom->createTextNode($copyright);
+        $copy->appendChild($text);
+    }
+
+    /**
+     * Set feed level logo (image)
+     *
+     * @param DOMDocument $dom
+     * @param DOMElement $root
+     * @return void
+     */
+    protected function _setImage(DOMDocument $dom, DOMElement $root)
+    {
+        $image = $this->getDataContainer()->getImage();
+        if (!$image) {
+            return;
+        }
+        $img = $dom->createElement('logo');
+        $root->appendChild($img);
+        $text = $dom->createTextNode($image['uri']);
+        $img->appendChild($text);
+    }
+
+    /**
+     * Set date feed was created
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setDateCreated(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getDateCreated()) {
+            return;
+        }
+        if (!$this->getDataContainer()->getDateModified()) {
+            $this->getDataContainer()->setDateModified(
+                $this->getDataContainer()->getDateCreated()
+            );
+        }
+    }
+
+    /**
+     * Set base URL to feed links
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setBaseUrl(DOMDocument $dom, DOMElement $root)
+    {
+        $baseUrl = $this->getDataContainer()->getBaseUrl();
+        if (!$baseUrl) {
+            return;
+        }
+        $root->setAttribute('xml:base', $baseUrl);
+    }
+
+    /**
+     * Set hubs to which this feed pushes
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setHubs(DOMDocument $dom, DOMElement $root)
+    {
+        $hubs = $this->getDataContainer()->getHubs();
+        if (!$hubs) {
+            return;
+        }
+        foreach ($hubs as $hubUrl) {
+            $hub = $dom->createElement('link');
+            $hub->setAttribute('rel', 'hub');
+            $hub->setAttribute('href', $hubUrl);
+            $root->appendChild($hub);
+        }
+    }
+
+    /**
+     * Set feed categories
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setCategories(DOMDocument $dom, DOMElement $root)
+    {
+        $categories = $this->getDataContainer()->getCategories();
+        if (!$categories) {
+            return;
+        }
+        foreach ($categories as $cat) {
+            $category = $dom->createElement('category');
+            $category->setAttribute('term', $cat['term']);
+            if (isset($cat['label'])) {
+                $category->setAttribute('label', $cat['label']);
+            } else {
+                $category->setAttribute('label', $cat['term']);
+            }
+            if (isset($cat['scheme'])) {
+                $category->setAttribute('scheme', $cat['scheme']);
+            }
+            $root->appendChild($category);
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Feed/Atom.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Feed/Atom.php
new file mode 100644
index 000000000000..78abdd55a17d
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Feed/Atom.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Renderer\Feed;
+
+use DOMDocument;
+use Zend\Feed\Writer;
+use Zend\Feed\Writer\Renderer;
+
+/**
+*/
+class Atom extends AbstractAtom implements Renderer\RendererInterface
+{
+    /**
+     * Constructor
+     *
+     * @param  Writer\Feed $container
+     */
+    public function __construct (Writer\Feed $container)
+    {
+        parent::__construct($container);
+    }
+
+    /**
+     * Render Atom feed
+     *
+     * @return Atom
+     */
+    public function render()
+    {
+        if (!$this->container->getEncoding()) {
+            $this->container->setEncoding('UTF-8');
+        }
+        $this->dom = new DOMDocument('1.0', $this->container->getEncoding());
+        $this->dom->formatOutput = true;
+        $root = $this->dom->createElementNS(
+            Writer\Writer::NAMESPACE_ATOM_10, 'feed'
+        );
+        $this->setRootElement($root);
+        $this->dom->appendChild($root);
+        $this->_setLanguage($this->dom, $root);
+        $this->_setBaseUrl($this->dom, $root);
+        $this->_setTitle($this->dom, $root);
+        $this->_setDescription($this->dom, $root);
+        $this->_setImage($this->dom, $root);
+        $this->_setDateCreated($this->dom, $root);
+        $this->_setDateModified($this->dom, $root);
+        $this->_setGenerator($this->dom, $root);
+        $this->_setLink($this->dom, $root);
+        $this->_setFeedLinks($this->dom, $root);
+        $this->_setId($this->dom, $root);
+        $this->_setAuthors($this->dom, $root);
+        $this->_setCopyright($this->dom, $root);
+        $this->_setCategories($this->dom, $root);
+        $this->_setHubs($this->dom, $root);
+
+        foreach ($this->extensions as $ext) {
+            $ext->setType($this->getType());
+            $ext->setRootElement($this->getRootElement());
+            $ext->setDOMDocument($this->getDOMDocument(), $root);
+            $ext->render();
+        }
+
+        foreach ($this->container as $entry) {
+            if ($this->getDataContainer()->getEncoding()) {
+                $entry->setEncoding($this->getDataContainer()->getEncoding());
+            }
+            if ($entry instanceof Writer\Entry) {
+                $renderer = new Renderer\Entry\Atom($entry);
+            } else {
+                if (!$this->dom->documentElement->hasAttribute('xmlns:at')) {
+                    $this->dom->documentElement->setAttribute(
+                        'xmlns:at', 'http://purl.org/atompub/tombstones/1.0'
+                    );
+                }
+                $renderer = new Renderer\Entry\AtomDeleted($entry);
+            }
+            if ($this->ignoreExceptions === true) {
+                $renderer->ignoreExceptions();
+            }
+            $renderer->setType($this->getType());
+            $renderer->setRootElement($this->dom->documentElement);
+            $renderer->render();
+            $element = $renderer->getElement();
+            $imported = $this->dom->importNode($element, true);
+            $root->appendChild($imported);
+        }
+        return $this;
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Feed/Atom/AbstractAtom.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Feed/Atom/AbstractAtom.php
new file mode 100644
index 000000000000..a36dab28eaf3
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Feed/Atom/AbstractAtom.php
@@ -0,0 +1,400 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Renderer\Feed\Atom;
+
+use Datetime;
+use DOMDocument;
+use DOMElement;
+use Zend\Feed;
+use Zend\Feed\Writer\Version;
+
+class AbstractAtom extends Feed\Writer\Renderer\AbstractRenderer
+{
+    /**
+     * Constructor
+     *
+     * @param  \Zend\Feed\Writer\Feed $container
+     */
+    public function __construct ($container)
+    {
+        parent::__construct($container);
+    }
+
+    /**
+     * Set feed language
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setLanguage(DOMDocument $dom, DOMElement $root)
+    {
+        if ($this->getDataContainer()->getLanguage()) {
+            $root->setAttribute('xml:lang', $this->getDataContainer()
+                ->getLanguage());
+        }
+    }
+
+    /**
+     * Set feed title
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     * @throws Feed\Exception\InvalidArgumentException
+     */
+    protected function _setTitle(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getTitle()) {
+            $message = 'Atom 1.0 feed elements MUST contain exactly one'
+                . ' atom:title element but a title has not been set';
+            $exception = new Feed\Exception\InvalidArgumentException($message);
+            if (!$this->ignoreExceptions) {
+                throw $exception;
+            } else {
+                $this->exceptions[] = $exception;
+                return;
+            }
+        }
+
+        $title = $dom->createElement('title');
+        $root->appendChild($title);
+        $title->setAttribute('type', 'text');
+        $text = $dom->createTextNode($this->getDataContainer()->getTitle());
+        $title->appendChild($text);
+    }
+
+    /**
+     * Set feed description
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setDescription(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getDescription()) {
+            return;
+        }
+        $subtitle = $dom->createElement('subtitle');
+        $root->appendChild($subtitle);
+        $subtitle->setAttribute('type', 'text');
+        $text = $dom->createTextNode($this->getDataContainer()->getDescription());
+        $subtitle->appendChild($text);
+    }
+
+    /**
+     * Set date feed was last modified
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     * @throws Feed\Exception\InvalidArgumentException
+     */
+    protected function _setDateModified(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getDateModified()) {
+            $message = 'Atom 1.0 feed elements MUST contain exactly one'
+                . ' atom:updated element but a modification date has not been set';
+            $exception = new Feed\Exception\InvalidArgumentException($message);
+            if (!$this->ignoreExceptions) {
+                throw $exception;
+            } else {
+                $this->exceptions[] = $exception;
+                return;
+            }
+        }
+
+        $updated = $dom->createElement('updated');
+        $root->appendChild($updated);
+        $text = $dom->createTextNode(
+            $this->getDataContainer()->getDateModified()->format(DateTime::ISO8601)
+        );
+        $updated->appendChild($text);
+    }
+
+    /**
+     * Set feed generator string
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setGenerator(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getGenerator()) {
+            $this->getDataContainer()->setGenerator('Zend_Feed_Writer',
+                Version::VERSION, 'http://framework.zend.com');
+        }
+
+        $gdata = $this->getDataContainer()->getGenerator();
+        $generator = $dom->createElement('generator');
+        $root->appendChild($generator);
+        $text = $dom->createTextNode($gdata['name']);
+        $generator->appendChild($text);
+        if (array_key_exists('uri', $gdata)) {
+            $generator->setAttribute('uri', $gdata['uri']);
+        }
+        if (array_key_exists('version', $gdata)) {
+            $generator->setAttribute('version', $gdata['version']);
+        }
+    }
+
+    /**
+     * Set link to feed
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setLink(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getLink()) {
+            return;
+        }
+        $link = $dom->createElement('link');
+        $root->appendChild($link);
+        $link->setAttribute('rel', 'alternate');
+        $link->setAttribute('type', 'text/html');
+        $link->setAttribute('href', $this->getDataContainer()->getLink());
+    }
+
+    /**
+     * Set feed links
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     * @throws Feed\Exception\InvalidArgumentException
+     */
+    protected function _setFeedLinks(DOMDocument $dom, DOMElement $root)
+    {
+        $flinks = $this->getDataContainer()->getFeedLinks();
+        if (!$flinks || !array_key_exists('atom', $flinks)) {
+            $message = 'Atom 1.0 feed elements SHOULD contain one atom:link '
+                . 'element with a rel attribute value of "self".  This is the '
+                . 'preferred URI for retrieving Atom Feed Documents representing '
+                . 'this Atom feed but a feed link has not been set';
+            $exception = new Feed\Exception\InvalidArgumentException($message);
+            if (!$this->ignoreExceptions) {
+                throw $exception;
+            } else {
+                $this->exceptions[] = $exception;
+                return;
+            }
+        }
+
+        foreach ($flinks as $type => $href) {
+            $mime = 'application/' . strtolower($type) . '+xml';
+            $flink = $dom->createElement('link');
+            $root->appendChild($flink);
+            $flink->setAttribute('rel', 'self');
+            $flink->setAttribute('type', $mime);
+            $flink->setAttribute('href', $href);
+        }
+    }
+
+    /**
+     * Set feed authors
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setAuthors(DOMDocument $dom, DOMElement $root)
+    {
+        $authors = $this->container->getAuthors();
+        if (!$authors || empty($authors)) {
+            /**
+             * Technically we should defer an exception until we can check
+             * that all entries contain an author. If any entry is missing
+             * an author, then a missing feed author element is invalid
+             */
+            return;
+        }
+        foreach ($authors as $data) {
+            $author = $this->dom->createElement('author');
+            $name = $this->dom->createElement('name');
+            $author->appendChild($name);
+            $root->appendChild($author);
+            $text = $dom->createTextNode($data['name']);
+            $name->appendChild($text);
+            if (array_key_exists('email', $data)) {
+                $email = $this->dom->createElement('email');
+                $author->appendChild($email);
+                $text = $dom->createTextNode($data['email']);
+                $email->appendChild($text);
+            }
+            if (array_key_exists('uri', $data)) {
+                $uri = $this->dom->createElement('uri');
+                $author->appendChild($uri);
+                $text = $dom->createTextNode($data['uri']);
+                $uri->appendChild($text);
+            }
+        }
+    }
+
+    /**
+     * Set feed identifier
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     * @throws Feed\Exception\InvalidArgumentException
+     */
+    protected function _setId(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getId()
+        && !$this->getDataContainer()->getLink()) {
+            $message = 'Atom 1.0 feed elements MUST contain exactly one '
+                . 'atom:id element, or as an alternative, we can use the same '
+                . 'value as atom:link however neither a suitable link nor an '
+                . 'id have been set';
+            $exception = new Feed\Exception\InvalidArgumentException($message);
+            if (!$this->ignoreExceptions) {
+                throw $exception;
+            } else {
+                $this->exceptions[] = $exception;
+                return;
+            }
+        }
+
+        if (!$this->getDataContainer()->getId()) {
+            $this->getDataContainer()->setId(
+                $this->getDataContainer()->getLink());
+        }
+        $id = $dom->createElement('id');
+        $root->appendChild($id);
+        $text = $dom->createTextNode($this->getDataContainer()->getId());
+        $id->appendChild($text);
+    }
+
+    /**
+     * Set feed copyright
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setCopyright(DOMDocument $dom, DOMElement $root)
+    {
+        $copyright = $this->getDataContainer()->getCopyright();
+        if (!$copyright) {
+            return;
+        }
+        $copy = $dom->createElement('rights');
+        $root->appendChild($copy);
+        $text = $dom->createTextNode($copyright);
+        $copy->appendChild($text);
+    }
+    /**
+     * Set feed level logo (image)
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setImage(DOMDocument $dom, DOMElement $root)
+    {
+        $image = $this->getDataContainer()->getImage();
+        if (!$image) {
+            return;
+        }
+        $img = $dom->createElement('logo');
+        $root->appendChild($img);
+        $text = $dom->createTextNode($image['uri']);
+        $img->appendChild($text);
+    }
+
+
+    /**
+     * Set date feed was created
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setDateCreated(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getDateCreated()) {
+            return;
+        }
+        if (!$this->getDataContainer()->getDateModified()) {
+            $this->getDataContainer()->setDateModified(
+                $this->getDataContainer()->getDateCreated()
+            );
+        }
+    }
+
+    /**
+     * Set base URL to feed links
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setBaseUrl(DOMDocument $dom, DOMElement $root)
+    {
+        $baseUrl = $this->getDataContainer()->getBaseUrl();
+        if (!$baseUrl) {
+            return;
+        }
+        $root->setAttribute('xml:base', $baseUrl);
+    }
+
+    /**
+     * Set hubs to which this feed pushes
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setHubs(DOMDocument $dom, DOMElement $root)
+    {
+        $hubs = $this->getDataContainer()->getHubs();
+        if (!$hubs) {
+            return;
+        }
+        foreach ($hubs as $hubUrl) {
+            $hub = $dom->createElement('link');
+            $hub->setAttribute('rel', 'hub');
+            $hub->setAttribute('href', $hubUrl);
+            $root->appendChild($hub);
+        }
+    }
+
+    /**
+     * Set feed categories
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setCategories(DOMDocument $dom, DOMElement $root)
+    {
+        $categories = $this->getDataContainer()->getCategories();
+        if (!$categories) {
+            return;
+        }
+        foreach ($categories as $cat) {
+            $category = $dom->createElement('category');
+            $category->setAttribute('term', $cat['term']);
+            if (isset($cat['label'])) {
+                $category->setAttribute('label', $cat['label']);
+            } else {
+                $category->setAttribute('label', $cat['term']);
+            }
+            if (isset($cat['scheme'])) {
+                $category->setAttribute('scheme', $cat['scheme']);
+            }
+            $root->appendChild($category);
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Feed/Atom/Source.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Feed/Atom/Source.php
new file mode 100644
index 000000000000..f9fbf2d957f9
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Feed/Atom/Source.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Renderer\Feed\Atom;
+
+use DOMDocument;
+use DOMElement;
+
+class Source extends AbstractAtom implements \Zend\Feed\Writer\Renderer\RendererInterface
+{
+
+    /**
+     * Constructor
+     *
+     * @param  \Zend\Feed\Writer\Source $container
+     */
+    public function __construct (\Zend\Feed\Writer\Source $container)
+    {
+        parent::__construct($container);
+    }
+
+    /**
+     * Render Atom Feed Metadata (Source element)
+     *
+     * @return \Zend\Feed\Writer\Renderer\Feed\Atom
+     */
+    public function render()
+    {
+        if (!$this->container->getEncoding()) {
+            $this->container->setEncoding('UTF-8');
+        }
+        $this->dom = new DOMDocument('1.0', $this->container->getEncoding());
+        $this->dom->formatOutput = true;
+        $root = $this->dom->createElement('source');
+        $this->setRootElement($root);
+        $this->dom->appendChild($root);
+        $this->_setLanguage($this->dom, $root);
+        $this->_setBaseUrl($this->dom, $root);
+        $this->_setTitle($this->dom, $root);
+        $this->_setDescription($this->dom, $root);
+        $this->_setDateCreated($this->dom, $root);
+        $this->_setDateModified($this->dom, $root);
+        $this->_setGenerator($this->dom, $root);
+        $this->_setLink($this->dom, $root);
+        $this->_setFeedLinks($this->dom, $root);
+        $this->_setId($this->dom, $root);
+        $this->_setAuthors($this->dom, $root);
+        $this->_setCopyright($this->dom, $root);
+        $this->_setCategories($this->dom, $root);
+
+        foreach ($this->extensions as $ext) {
+            $ext->setType($this->getType());
+            $ext->setRootElement($this->getRootElement());
+            $ext->setDomDocument($this->getDomDocument(), $root);
+            $ext->render();
+        }
+        return $this;
+    }
+
+    /**
+     * Set feed generator string
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setGenerator(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getGenerator()) {
+            return;
+        }
+
+        $gdata = $this->getDataContainer()->getGenerator();
+        $generator = $dom->createElement('generator');
+        $root->appendChild($generator);
+        $text = $dom->createTextNode($gdata['name']);
+        $generator->appendChild($text);
+        if (array_key_exists('uri', $gdata)) {
+            $generator->setAttribute('uri', $gdata['uri']);
+        }
+        if (array_key_exists('version', $gdata)) {
+            $generator->setAttribute('version', $gdata['version']);
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Feed/AtomSource.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Feed/AtomSource.php
new file mode 100644
index 000000000000..de9654c58e4c
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Feed/AtomSource.php
@@ -0,0 +1,95 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Renderer\Feed;
+
+use DOMDocument;
+use DOMElement;
+use Zend\Feed\Writer;
+use Zend\Feed\Writer\Renderer;
+
+/**
+*/
+class AtomSource extends AbstractAtom implements Renderer\RendererInterface
+{
+
+    /**
+     * Constructor
+     *
+     * @param  Writer\Source $container
+     */
+    public function __construct (Writer\Source $container)
+    {
+        parent::__construct($container);
+    }
+
+    /**
+     * Render Atom Feed Metadata (Source element)
+     *
+     * @return \Zend\Feed\Writer\Renderer\Feed\Atom
+     */
+    public function render()
+    {
+        if (!$this->container->getEncoding()) {
+            $this->container->setEncoding('UTF-8');
+        }
+        $this->dom = new DOMDocument('1.0', $this->container->getEncoding());
+        $this->dom->formatOutput = true;
+        $root = $this->dom->createElement('source');
+        $this->setRootElement($root);
+        $this->dom->appendChild($root);
+        $this->_setLanguage($this->dom, $root);
+        $this->_setBaseUrl($this->dom, $root);
+        $this->_setTitle($this->dom, $root);
+        $this->_setDescription($this->dom, $root);
+        $this->_setDateCreated($this->dom, $root);
+        $this->_setDateModified($this->dom, $root);
+        $this->_setGenerator($this->dom, $root);
+        $this->_setLink($this->dom, $root);
+        $this->_setFeedLinks($this->dom, $root);
+        $this->_setId($this->dom, $root);
+        $this->_setAuthors($this->dom, $root);
+        $this->_setCopyright($this->dom, $root);
+        $this->_setCategories($this->dom, $root);
+
+        foreach ($this->extensions as $ext) {
+            $ext->setType($this->getType());
+            $ext->setRootElement($this->getRootElement());
+            $ext->setDOMDocument($this->getDOMDocument(), $root);
+            $ext->render();
+        }
+        return $this;
+    }
+
+    /**
+     * Set feed generator string
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setGenerator(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getGenerator()) {
+            return;
+        }
+
+        $gdata = $this->getDataContainer()->getGenerator();
+        $generator = $dom->createElement('generator');
+        $root->appendChild($generator);
+        $text = $dom->createTextNode($gdata['name']);
+        $generator->appendChild($text);
+        if (array_key_exists('uri', $gdata)) {
+            $generator->setAttribute('uri', $gdata['uri']);
+        }
+        if (array_key_exists('version', $gdata)) {
+            $generator->setAttribute('version', $gdata['version']);
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Feed/Rss.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Feed/Rss.php
new file mode 100644
index 000000000000..84056a92286c
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/Feed/Rss.php
@@ -0,0 +1,484 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Renderer\Feed;
+
+use DateTime;
+use DOMDocument;
+use DOMElement;
+use Zend\Feed\Uri;
+use Zend\Feed\Writer;
+use Zend\Feed\Writer\Renderer;
+use Zend\Feed\Writer\Version;
+
+/**
+*/
+class Rss extends Renderer\AbstractRenderer implements Renderer\RendererInterface
+{
+    /**
+     * Constructor
+     *
+     * @param  Writer\Feed $container
+     */
+    public function __construct (Writer\Feed $container)
+    {
+        parent::__construct($container);
+    }
+
+    /**
+     * Render RSS feed
+     *
+     * @return self
+     */
+    public function render()
+    {
+        $this->dom = new DOMDocument('1.0', $this->container->getEncoding());
+        $this->dom->formatOutput = true;
+        $this->dom->substituteEntities = false;
+        $rss = $this->dom->createElement('rss');
+        $this->setRootElement($rss);
+        $rss->setAttribute('version', '2.0');
+
+        $channel = $this->dom->createElement('channel');
+        $rss->appendChild($channel);
+        $this->dom->appendChild($rss);
+        $this->_setLanguage($this->dom, $channel);
+        $this->_setBaseUrl($this->dom, $channel);
+        $this->_setTitle($this->dom, $channel);
+        $this->_setDescription($this->dom, $channel);
+        $this->_setImage($this->dom, $channel);
+        $this->_setDateCreated($this->dom, $channel);
+        $this->_setDateModified($this->dom, $channel);
+        $this->_setLastBuildDate($this->dom, $channel);
+        $this->_setGenerator($this->dom, $channel);
+        $this->_setLink($this->dom, $channel);
+        $this->_setAuthors($this->dom, $channel);
+        $this->_setCopyright($this->dom, $channel);
+        $this->_setCategories($this->dom, $channel);
+
+        foreach ($this->extensions as $ext) {
+            $ext->setType($this->getType());
+            $ext->setRootElement($this->getRootElement());
+            $ext->setDOMDocument($this->getDOMDocument(), $channel);
+            $ext->render();
+        }
+
+        foreach ($this->container as $entry) {
+            if ($this->getDataContainer()->getEncoding()) {
+                $entry->setEncoding($this->getDataContainer()->getEncoding());
+            }
+            if ($entry instanceof Writer\Entry) {
+                $renderer = new Renderer\Entry\Rss($entry);
+            } else {
+                continue;
+            }
+            if ($this->ignoreExceptions === true) {
+                $renderer->ignoreExceptions();
+            }
+            $renderer->setType($this->getType());
+            $renderer->setRootElement($this->dom->documentElement);
+            $renderer->render();
+            $element = $renderer->getElement();
+            $imported = $this->dom->importNode($element, true);
+            $channel->appendChild($imported);
+        }
+        return $this;
+    }
+
+    /**
+     * Set feed language
+     *
+     * @param DOMDocument $dom
+     * @param DOMElement $root
+     * @return void
+     */
+    protected function _setLanguage(DOMDocument $dom, DOMElement $root)
+    {
+        $lang = $this->getDataContainer()->getLanguage();
+        if (!$lang) {
+            return;
+        }
+        $language = $dom->createElement('language');
+        $root->appendChild($language);
+        $language->nodeValue = $lang;
+    }
+
+    /**
+     * Set feed title
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    protected function _setTitle(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getTitle()) {
+            $message = 'RSS 2.0 feed elements MUST contain exactly one'
+            . ' title element but a title has not been set';
+            $exception = new Writer\Exception\InvalidArgumentException($message);
+            if (!$this->ignoreExceptions) {
+                throw $exception;
+            } else {
+                $this->exceptions[] = $exception;
+                return;
+            }
+        }
+
+        $title = $dom->createElement('title');
+        $root->appendChild($title);
+        $text = $dom->createTextNode($this->getDataContainer()->getTitle());
+        $title->appendChild($text);
+    }
+
+    /**
+     * Set feed description
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    protected function _setDescription(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getDescription()) {
+            $message = 'RSS 2.0 feed elements MUST contain exactly one'
+            . ' description element but one has not been set';
+            $exception = new Writer\Exception\InvalidArgumentException($message);
+            if (!$this->ignoreExceptions) {
+                throw $exception;
+            } else {
+                $this->exceptions[] = $exception;
+                return;
+            }
+        }
+        $subtitle = $dom->createElement('description');
+        $root->appendChild($subtitle);
+        $text = $dom->createTextNode($this->getDataContainer()->getDescription());
+        $subtitle->appendChild($text);
+    }
+
+    /**
+     * Set date feed was last modified
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setDateModified(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getDateModified()) {
+            return;
+        }
+
+        $updated = $dom->createElement('pubDate');
+        $root->appendChild($updated);
+        $text = $dom->createTextNode(
+            $this->getDataContainer()->getDateModified()->format(DateTime::RSS)
+        );
+        $updated->appendChild($text);
+    }
+
+    /**
+     * Set feed generator string
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setGenerator(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getGenerator()) {
+            $this->getDataContainer()->setGenerator('Zend_Feed_Writer',
+                Version::VERSION, 'http://framework.zend.com');
+        }
+
+        $gdata = $this->getDataContainer()->getGenerator();
+        $generator = $dom->createElement('generator');
+        $root->appendChild($generator);
+        $name = $gdata['name'];
+        if (array_key_exists('version', $gdata)) {
+            $name .= ' ' . $gdata['version'];
+        }
+        if (array_key_exists('uri', $gdata)) {
+            $name .= ' (' . $gdata['uri'] . ')';
+        }
+        $text = $dom->createTextNode($name);
+        $generator->appendChild($text);
+    }
+
+    /**
+     * Set link to feed
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    protected function _setLink(DOMDocument $dom, DOMElement $root)
+    {
+        $value = $this->getDataContainer()->getLink();
+        if (!$value) {
+            $message = 'RSS 2.0 feed elements MUST contain exactly one'
+            . ' link element but one has not been set';
+            $exception = new Writer\Exception\InvalidArgumentException($message);
+            if (!$this->ignoreExceptions) {
+                throw $exception;
+            } else {
+                $this->exceptions[] = $exception;
+                return;
+            }
+        }
+        $link = $dom->createElement('link');
+        $root->appendChild($link);
+        $text = $dom->createTextNode($value);
+        $link->appendChild($text);
+        if (!Uri::factory($value)->isValid()) {
+            $link->setAttribute('isPermaLink', 'false');
+        }
+    }
+
+    /**
+     * Set feed authors
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setAuthors(DOMDocument $dom, DOMElement $root)
+    {
+        $authors = $this->getDataContainer()->getAuthors();
+        if (!$authors || empty($authors)) {
+            return;
+        }
+        foreach ($authors as $data) {
+            $author = $this->dom->createElement('author');
+            $name = $data['name'];
+            if (array_key_exists('email', $data)) {
+                $name = $data['email'] . ' (' . $data['name'] . ')';
+            }
+            $text = $dom->createTextNode($name);
+            $author->appendChild($text);
+            $root->appendChild($author);
+        }
+    }
+
+    /**
+     * Set feed copyright
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setCopyright(DOMDocument $dom, DOMElement $root)
+    {
+        $copyright = $this->getDataContainer()->getCopyright();
+        if (!$copyright) {
+            return;
+        }
+        $copy = $dom->createElement('copyright');
+        $root->appendChild($copy);
+        $text = $dom->createTextNode($copyright);
+        $copy->appendChild($text);
+    }
+
+    /**
+     * Set feed channel image
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     * @throws Writer\Exception\InvalidArgumentException
+     */
+    protected function _setImage(DOMDocument $dom, DOMElement $root)
+    {
+        $image = $this->getDataContainer()->getImage();
+        if (!$image) {
+            return;
+        }
+
+        if (!isset($image['title']) || empty($image['title'])
+            || !is_string($image['title'])
+        ) {
+            $message = 'RSS 2.0 feed images must include a title';
+            $exception = new Writer\Exception\InvalidArgumentException($message);
+            if (!$this->ignoreExceptions) {
+                throw $exception;
+            } else {
+                $this->exceptions[] = $exception;
+                return;
+            }
+        }
+
+        if (empty($image['link']) || !is_string($image['link'])
+            || !Uri::factory($image['link'])->isValid()
+        ) {
+            $message = 'Invalid parameter: parameter \'link\''
+            . ' must be a non-empty string and valid URI/IRI';
+            $exception = new Writer\Exception\InvalidArgumentException($message);
+            if (!$this->ignoreExceptions) {
+                throw $exception;
+            } else {
+                $this->exceptions[] = $exception;
+                return;
+            }
+        }
+
+        $img   = $dom->createElement('image');
+        $root->appendChild($img);
+
+        $url   = $dom->createElement('url');
+        $text  = $dom->createTextNode($image['uri']);
+        $url->appendChild($text);
+
+        $title = $dom->createElement('title');
+        $text  = $dom->createTextNode($image['title']);
+        $title->appendChild($text);
+
+        $link  = $dom->createElement('link');
+        $text  = $dom->createTextNode($image['link']);
+        $link->appendChild($text);
+
+        $img->appendChild($url);
+        $img->appendChild($title);
+        $img->appendChild($link);
+
+        if (isset($image['height'])) {
+            if (!ctype_digit((string) $image['height']) || $image['height'] > 400) {
+                $message = 'Invalid parameter: parameter \'height\''
+                         . ' must be an integer not exceeding 400';
+                $exception = new Writer\Exception\InvalidArgumentException($message);
+                if (!$this->ignoreExceptions) {
+                    throw $exception;
+                } else {
+                    $this->exceptions[] = $exception;
+                    return;
+                }
+            }
+            $height = $dom->createElement('height');
+            $text   = $dom->createTextNode($image['height']);
+            $height->appendChild($text);
+            $img->appendChild($height);
+        }
+        if (isset($image['width'])) {
+            if (!ctype_digit((string) $image['width']) || $image['width'] > 144) {
+                $message = 'Invalid parameter: parameter \'width\''
+                         . ' must be an integer not exceeding 144';
+                $exception = new Writer\Exception\InvalidArgumentException($message);
+                if (!$this->ignoreExceptions) {
+                    throw $exception;
+                } else {
+                    $this->exceptions[] = $exception;
+                    return;
+                }
+            }
+            $width = $dom->createElement('width');
+            $text  = $dom->createTextNode($image['width']);
+            $width->appendChild($text);
+            $img->appendChild($width);
+        }
+        if (isset($image['description'])) {
+            if (empty($image['description']) || !is_string($image['description'])) {
+                $message = 'Invalid parameter: parameter \'description\''
+                         . ' must be a non-empty string';
+                $exception = new Writer\Exception\InvalidArgumentException($message);
+                if (!$this->ignoreExceptions) {
+                    throw $exception;
+                } else {
+                    $this->exceptions[] = $exception;
+                    return;
+                }
+            }
+            $desc = $dom->createElement('description');
+            $text = $dom->createTextNode($image['description']);
+            $desc->appendChild($text);
+            $img->appendChild($desc);
+        }
+    }
+
+    /**
+     * Set date feed was created
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setDateCreated(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getDateCreated()) {
+            return;
+        }
+        if (!$this->getDataContainer()->getDateModified()) {
+            $this->getDataContainer()->setDateModified(
+                $this->getDataContainer()->getDateCreated()
+            );
+        }
+    }
+
+    /**
+     * Set date feed last build date
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setLastBuildDate(DOMDocument $dom, DOMElement $root)
+    {
+        if (!$this->getDataContainer()->getLastBuildDate()) {
+            return;
+        }
+
+        $lastBuildDate = $dom->createElement('lastBuildDate');
+        $root->appendChild($lastBuildDate);
+        $text = $dom->createTextNode(
+            $this->getDataContainer()->getLastBuildDate()->format(DateTime::RSS)
+        );
+        $lastBuildDate->appendChild($text);
+    }
+
+    /**
+     * Set base URL to feed links
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setBaseUrl(DOMDocument $dom, DOMElement $root)
+    {
+        $baseUrl = $this->getDataContainer()->getBaseUrl();
+        if (!$baseUrl) {
+            return;
+        }
+        $root->setAttribute('xml:base', $baseUrl);
+    }
+
+    /**
+     * Set feed categories
+     *
+     * @param  DOMDocument $dom
+     * @param  DOMElement $root
+     * @return void
+     */
+    protected function _setCategories(DOMDocument $dom, DOMElement $root)
+    {
+        $categories = $this->getDataContainer()->getCategories();
+        if (!$categories) {
+            return;
+        }
+        foreach ($categories as $cat) {
+            $category = $dom->createElement('category');
+            if (isset($cat['scheme'])) {
+                $category->setAttribute('domain', $cat['scheme']);
+            }
+            $text = $dom->createTextNode($cat['term']);
+            $category->appendChild($text);
+            $root->appendChild($category);
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/RendererInterface.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/RendererInterface.php
new file mode 100644
index 000000000000..b9d47c3f1025
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Renderer/RendererInterface.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer\Renderer;
+
+use DOMDocument;
+use DOMElement;
+
+/**
+*/
+interface RendererInterface
+{
+    /**
+     * Render feed/entry
+     *
+     * @return void
+     */
+    public function render();
+
+    /**
+     * Save feed and/or entry to XML and return string
+     *
+     * @return string
+     */
+    public function saveXml();
+
+    /**
+     * Get DOM document
+     *
+     * @return DOMDocument
+     */
+    public function getDomDocument();
+
+    /**
+     * Get document element from DOM
+     *
+     * @return DOMElement
+     */
+    public function getElement();
+
+    /**
+     * Get data container containing feed items
+     *
+     * @return mixed
+     */
+    public function getDataContainer();
+
+    /**
+     * Should exceptions be ignored?
+     *
+     * @return mixed
+     */
+    public function ignoreExceptions();
+
+    /**
+     * Get list of thrown exceptions
+     *
+     * @return array
+     */
+    public function getExceptions();
+
+    /**
+     * Set the current feed type being exported to "rss" or "atom". This allows
+     * other objects to gracefully choose whether to execute or not, depending
+     * on their appropriateness for the current type, e.g. renderers.
+     *
+     * @param string $type
+     */
+    public function setType($type);
+
+    /**
+     * Retrieve the current or last feed type exported.
+     *
+     * @return string Value will be "rss" or "atom"
+     */
+    public function getType();
+
+    /**
+     * Sets the absolute root element for the XML feed being generated. This
+     * helps simplify the appending of namespace declarations, but also ensures
+     * namespaces are added to the root element - not scattered across the entire
+     * XML file - may assist namespace unsafe parsers and looks pretty ;).
+     *
+     * @param DOMElement $root
+     */
+    public function setRootElement(DOMElement $root);
+
+    /**
+     * Retrieve the absolute root element for the XML feed being generated.
+     *
+     * @return DOMElement
+     */
+    public function getRootElement();
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Source.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Source.php
new file mode 100644
index 000000000000..ff4534db16a3
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Source.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer;
+
+/**
+*/
+class Source extends AbstractFeed
+{
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Version.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Version.php
new file mode 100644
index 000000000000..806d5906d4cb
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Version.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer;
+
+abstract class Version
+{
+    const VERSION = '2';
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Writer.php b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Writer.php
new file mode 100644
index 000000000000..ccd69d4d01d7
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/Writer/Writer.php
@@ -0,0 +1,199 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Feed\Writer;
+
+/**
+*/
+class Writer
+{
+    /**
+     * Namespace constants
+     */
+    const NAMESPACE_ATOM_03  = 'http://purl.org/atom/ns#';
+    const NAMESPACE_ATOM_10  = 'http://www.w3.org/2005/Atom';
+    const NAMESPACE_RDF      = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
+    const NAMESPACE_RSS_090  = 'http://my.netscape.com/rdf/simple/0.9/';
+    const NAMESPACE_RSS_10   = 'http://purl.org/rss/1.0/';
+
+    /**
+     * Feed type constants
+     */
+    const TYPE_ANY              = 'any';
+    const TYPE_ATOM_03          = 'atom-03';
+    const TYPE_ATOM_10          = 'atom-10';
+    const TYPE_ATOM_ANY         = 'atom';
+    const TYPE_RSS_090          = 'rss-090';
+    const TYPE_RSS_091          = 'rss-091';
+    const TYPE_RSS_091_NETSCAPE = 'rss-091n';
+    const TYPE_RSS_091_USERLAND = 'rss-091u';
+    const TYPE_RSS_092          = 'rss-092';
+    const TYPE_RSS_093          = 'rss-093';
+    const TYPE_RSS_094          = 'rss-094';
+    const TYPE_RSS_10           = 'rss-10';
+    const TYPE_RSS_20           = 'rss-20';
+    const TYPE_RSS_ANY          = 'rss';
+
+    /**
+     * @var ExtensionManagerInterface
+     */
+    protected static $extensionManager = null;
+
+    /**
+     * Array of registered extensions by class postfix (after the base class
+     * name) across four categories - data containers and renderers for entry
+     * and feed levels.
+     *
+     * @var array
+     */
+    protected static $extensions = array(
+        'entry'         => array(),
+        'feed'          => array(),
+        'entryRenderer' => array(),
+        'feedRenderer'  => array(),
+    );
+
+    /**
+     * Set plugin loader for use with Extensions
+     *
+     * @param ExtensionManagerInterface
+     */
+    public static function setExtensionManager(ExtensionManagerInterface $extensionManager)
+    {
+        static::$extensionManager = $extensionManager;
+    }
+
+    /**
+     * Get plugin manager for use with Extensions
+     *
+     * @return ExtensionManagerInterface
+     */
+    public static function getExtensionManager()
+    {
+        if (!isset(static::$extensionManager)) {
+            static::setExtensionManager(new ExtensionManager());
+        }
+        return static::$extensionManager;
+    }
+
+    /**
+     * Register an Extension by name
+     *
+     * @param  string $name
+     * @return void
+     * @throws Exception\RuntimeException if unable to resolve Extension class
+     */
+    public static function registerExtension($name)
+    {
+        $feedName          = $name . '\Feed';
+        $entryName         = $name . '\Entry';
+        $feedRendererName  = $name . '\Renderer\Feed';
+        $entryRendererName = $name . '\Renderer\Entry';
+        $manager           = static::getExtensionManager();
+        if (static::isRegistered($name)) {
+            if ($manager->has($feedName)
+                || $manager->has($entryName)
+                || $manager->has($feedRendererName)
+                || $manager->has($entryRendererName)
+            ) {
+                return;
+            }
+        }
+        if (!$manager->has($feedName)
+            && !$manager->has($entryName)
+            && !$manager->has($feedRendererName)
+            && !$manager->has($entryRendererName)
+        ) {
+            throw new Exception\RuntimeException('Could not load extension: ' . $name
+                . 'using Plugin Loader. Check prefix paths are configured and extension exists.');
+        }
+        if ($manager->has($feedName)) {
+            static::$extensions['feed'][] = $feedName;
+        }
+        if ($manager->has($entryName)) {
+            static::$extensions['entry'][] = $entryName;
+        }
+        if ($manager->has($feedRendererName)) {
+            static::$extensions['feedRenderer'][] = $feedRendererName;
+        }
+        if ($manager->has($entryRendererName)) {
+            static::$extensions['entryRenderer'][] = $entryRendererName;
+        }
+    }
+
+    /**
+     * Is a given named Extension registered?
+     *
+     * @param  string $extensionName
+     * @return bool
+     */
+    public static function isRegistered($extensionName)
+    {
+        $feedName          = $extensionName . '\Feed';
+        $entryName         = $extensionName . '\Entry';
+        $feedRendererName  = $extensionName . '\Renderer\Feed';
+        $entryRendererName = $extensionName . '\Renderer\Entry';
+        if (in_array($feedName, static::$extensions['feed'])
+            || in_array($entryName, static::$extensions['entry'])
+            || in_array($feedRendererName, static::$extensions['feedRenderer'])
+            || in_array($entryRendererName, static::$extensions['entryRenderer'])
+        ) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Get a list of extensions
+     *
+     * @return array
+     */
+    public static function getExtensions()
+    {
+        return static::$extensions;
+    }
+
+    /**
+     * Reset class state to defaults
+     *
+     * @return void
+     */
+    public static function reset()
+    {
+        static::$extensionManager = null;
+        static::$extensions   = array(
+            'entry'         => array(),
+            'feed'          => array(),
+            'entryRenderer' => array(),
+            'feedRenderer'  => array(),
+        );
+    }
+
+    /**
+     * Register core (default) extensions
+     *
+     * @return void
+     */
+    public static function registerCoreExtensions()
+    {
+        static::registerExtension('DublinCore');
+        static::registerExtension('Content');
+        static::registerExtension('Atom');
+        static::registerExtension('Slash');
+        static::registerExtension('WellFormedWeb');
+        static::registerExtension('Threading');
+        static::registerExtension('ITunes');
+    }
+
+    public static function lcfirst($str)
+    {
+        $str[0] = strtolower($str[0]);
+        return $str;
+    }
+}
diff --git a/core/vendor/zendframework/zend-feed/Zend/Feed/composer.json b/core/vendor/zendframework/zend-feed/Zend/Feed/composer.json
new file mode 100644
index 000000000000..d55068f011fd
--- /dev/null
+++ b/core/vendor/zendframework/zend-feed/Zend/Feed/composer.json
@@ -0,0 +1,31 @@
+{
+    "name": "zendframework/zend-feed",
+    "description": "provides functionality for consuming RSS and Atom feeds",
+    "license": "BSD-3-Clause",
+    "keywords": [
+        "zf2",
+        "feed"
+    ],
+    "autoload": {
+        "psr-0": {
+            "Zend\\Feed\\": ""
+        }
+    },
+    "target-dir": "Zend/Feed",
+    "require": {
+        "php": ">=5.3.3",
+        "zendframework/zend-escaper": "self.version",
+        "zendframework/zend-stdlib": "self.version"
+    },
+    "suggest": {
+        "zendframework/zend-http": "Zend\\Http for PubSubHubbub, and optionally for use with Zend\\Feed\\Reader",
+        "zendframework/zend-servicemanager": "Zend\\ServiceManager component, for default/recommended ExtensionManager implementations",
+        "zendframework/zend-validator": "Zend\\Validator component"
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "2.2-dev",
+            "dev-develop": "2.3-dev"
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/AbstractOptions.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/AbstractOptions.php
new file mode 100644
index 000000000000..0e68c29e11c7
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/AbstractOptions.php
@@ -0,0 +1,161 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+use Traversable;
+
+abstract class AbstractOptions implements ParameterObjectInterface
+{
+    /**
+     * We use the __ prefix to avoid collisions with properties in
+     * user-implementations.
+     *
+     * @var bool
+     */
+    protected $__strictMode__ = true;
+
+    /**
+     * Constructor
+     *
+     * @param  array|Traversable|null $options
+     */
+    public function __construct($options = null)
+    {
+        if (null !== $options) {
+            $this->setFromArray($options);
+        }
+    }
+
+    /**
+     * Set one or more configuration properties
+     *
+     * @param  array|Traversable|AbstractOptions $options
+     * @throws Exception\InvalidArgumentException
+     * @return AbstractOptions Provides fluent interface
+     */
+    public function setFromArray($options)
+    {
+        if ($options instanceof self) {
+            $options = $options->toArray();
+        }
+
+        if (!is_array($options) && !$options instanceof Traversable) {
+            throw new Exception\InvalidArgumentException(sprintf(
+                'Parameter provided to %s must be an %s, %s or %s',
+                __METHOD__, 'array', 'Traversable', 'Zend\Stdlib\AbstractOptions'
+            ));
+        }
+
+        foreach ($options as $key => $value) {
+            $this->__set($key, $value);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Cast to array
+     *
+     * @return array
+     */
+    public function toArray()
+    {
+        $array = array();
+        $transform = function ($letters) {
+            $letter = array_shift($letters);
+            return '_' . strtolower($letter);
+        };
+        foreach ($this as $key => $value) {
+            if ($key === '__strictMode__') continue;
+            $normalizedKey = preg_replace_callback('/([A-Z])/', $transform, $key);
+            $array[$normalizedKey] = $value;
+        }
+        return $array;
+    }
+
+    /**
+     * Set a configuration property
+     *
+     * @see ParameterObject::__set()
+     * @param string $key
+     * @param mixed $value
+     * @throws Exception\BadMethodCallException
+     * @return void
+     */
+    public function __set($key, $value)
+    {
+        $setter = 'set' . str_replace(' ', '', ucwords(str_replace('_', ' ', $key)));
+        if ($this->__strictMode__ && !method_exists($this, $setter)) {
+            throw new Exception\BadMethodCallException(
+                'The option "' . $key . '" does not '
+                . 'have a matching ' . $setter . ' setter method '
+                . 'which must be defined'
+            );
+        } elseif (!$this->__strictMode__ && !method_exists($this, $setter)) {
+            return;
+        }
+        $this->{$setter}($value);
+    }
+
+    /**
+     * Get a configuration property
+     *
+     * @see ParameterObject::__get()
+     * @param string $key
+     * @throws Exception\BadMethodCallException
+     * @return mixed
+     */
+    public function __get($key)
+    {
+        $getter = 'get' . str_replace(' ', '', ucwords(str_replace('_', ' ', $key)));
+        if (!method_exists($this, $getter)) {
+            throw new Exception\BadMethodCallException(
+                'The option "' . $key . '" does not '
+                . 'have a matching ' . $getter . ' getter method '
+                . 'which must be defined'
+            );
+        }
+
+        return $this->{$getter}();
+    }
+
+    /**
+     * Test if a configuration property is null
+     * @see ParameterObject::__isset()
+     * @param string $key
+     * @return bool
+     */
+    public function __isset($key)
+    {
+        return null !== $this->__get($key);
+    }
+
+    /**
+     * Set a configuration property to NULL
+     *
+     * @see ParameterObject::__unset()
+     * @param string $key
+     * @throws Exception\InvalidArgumentException
+     * @return void
+     */
+    public function __unset($key)
+    {
+        try {
+            $this->__set($key, null);
+        } catch (Exception\BadMethodCallException $e) {
+            throw new Exception\InvalidArgumentException(
+                'The class property $' . $key . ' cannot be unset as'
+                    . ' NULL is an invalid value for it',
+                0,
+                $e
+            );
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ArrayObject.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ArrayObject.php
new file mode 100644
index 000000000000..806c128fc76f
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ArrayObject.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+/**
+ * If the version is less than 5.3.4, we'll use Zend\Stdlib\ArrayObject\PhpLegacyCompatibility
+ * which extends the native PHP ArrayObject implementation. For versions greater than or equal
+ * to 5.3.4, we'll use Zend\Stdlib\ArrayObject\PhpReferenceCompatibility, which corrects
+ * issues with how PHP handles references inside ArrayObject.
+ *
+ * class_alias is a global construct, so we can alias either one to Zend\Stdlib\ArrayObject,
+ * and from this point forward, that alias will be used.
+ */
+if (version_compare(PHP_VERSION, '5.3.4', 'lt')) {
+    class_alias('Zend\Stdlib\ArrayObject\PhpLegacyCompatibility', 'Zend\Stdlib\AbstractArrayObject');
+} else {
+    class_alias('Zend\Stdlib\ArrayObject\PhpReferenceCompatibility', 'Zend\Stdlib\AbstractArrayObject');
+}
+
+/**
+ * Custom framework ArrayObject implementation
+ *
+ * Extends version-specific "abstract" implementation.
+ */
+class ArrayObject extends AbstractArrayObject
+{
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ArrayObject/PhpLegacyCompatibility.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ArrayObject/PhpLegacyCompatibility.php
new file mode 100644
index 000000000000..9a71605e728e
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ArrayObject/PhpLegacyCompatibility.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\ArrayObject;
+
+use ArrayObject as PhpArrayObject;
+
+/**
+ * ArrayObject
+ *
+ * Since we need to substitute an alternate ArrayObject implementation for
+ * versions > 5.3.3, we need to provide a stub for 5.3.3. This stub
+ * simply extends the PHP ArrayObject implementation, and provides default
+ * behavior in the constructor.
+ */
+abstract class PhpLegacyCompatibility extends PhpArrayObject
+{
+    /**
+     * Constructor
+     *
+     * @param array  $input
+     * @param int    $flags
+     * @param string $iteratorClass
+     */
+    public function __construct($input = array(), $flags = self::STD_PROP_LIST, $iteratorClass = 'ArrayIterator')
+    {
+        parent::__construct($input, $flags, $iteratorClass);
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ArrayObject/PhpReferenceCompatibility.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ArrayObject/PhpReferenceCompatibility.php
new file mode 100644
index 000000000000..e25257c761b1
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ArrayObject/PhpReferenceCompatibility.php
@@ -0,0 +1,433 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\ArrayObject;
+
+use ArrayAccess;
+use Countable;
+use IteratorAggregate;
+use Serializable;
+use Zend\Stdlib\Exception;
+
+/**
+ * ArrayObject
+ *
+ * This ArrayObject is a rewrite of the implementation to fix
+ * issues with php's implementation of ArrayObject where you
+ * are unable to unset multi-dimensional arrays because you
+ * need to fetch the properties / lists as references.
+ */
+abstract class PhpReferenceCompatibility implements IteratorAggregate, ArrayAccess, Serializable, Countable
+{
+    /**
+     * Properties of the object have their normal functionality
+     * when accessed as list (var_dump, foreach, etc.).
+     */
+    const STD_PROP_LIST = 1;
+
+    /**
+     * Entries can be accessed as properties (read and write).
+     */
+    const ARRAY_AS_PROPS = 2;
+
+    /**
+     * @var array
+     */
+    protected $storage;
+
+    /**
+     * @var int
+     */
+    protected $flag;
+
+    /**
+     * @var string
+     */
+    protected $iteratorClass;
+
+    /**
+     * @var array
+     */
+    protected $protectedProperties;
+
+    /**
+     * Constructor
+     *
+     * @param array  $input
+     * @param int    $flags
+     * @param string $iteratorClass
+     */
+    public function __construct($input = array(), $flags = self::STD_PROP_LIST, $iteratorClass = 'ArrayIterator')
+    {
+        $this->setFlags($flags);
+        $this->storage = $input;
+        $this->setIteratorClass($iteratorClass);
+        $this->protectedProperties = array_keys(get_object_vars($this));
+    }
+
+    /**
+     * Returns whether the requested key exists
+     *
+     * @param  mixed $key
+     * @return bool
+     */
+    public function __isset($key)
+    {
+        if ($this->flag == self::ARRAY_AS_PROPS) {
+            return $this->offsetExists($key);
+        }
+        if (in_array($key, $this->protectedProperties)) {
+            throw new Exception\InvalidArgumentException('$key is a protected property, use a different key');
+        }
+
+        return isset($this->$key);
+    }
+
+    /**
+     * Sets the value at the specified key to value
+     *
+     * @param  mixed $key
+     * @param  mixed $value
+     * @return void
+     */
+    public function __set($key, $value)
+    {
+        if ($this->flag == self::ARRAY_AS_PROPS) {
+            return $this->offsetSet($key, $value);
+        }
+        if (in_array($key, $this->protectedProperties)) {
+            throw new Exception\InvalidArgumentException('$key is a protected property, use a different key');
+        }
+        $this->$key = $value;
+    }
+
+    /**
+     * Unsets the value at the specified key
+     *
+     * @param  mixed $key
+     * @return void
+     */
+    public function __unset($key)
+    {
+        if ($this->flag == self::ARRAY_AS_PROPS) {
+            return $this->offsetUnset($key);
+        }
+        if (in_array($key, $this->protectedProperties)) {
+            throw new Exception\InvalidArgumentException('$key is a protected property, use a different key');
+        }
+        unset($this->$key);
+    }
+
+    /**
+     * Returns the value at the specified key by reference
+     *
+     * @param  mixed $key
+     * @return mixed
+     */
+    public function &__get($key)
+    {
+        $ret = null;
+        if ($this->flag == self::ARRAY_AS_PROPS) {
+            $ret =& $this->offsetGet($key);
+
+            return $ret;
+        }
+        if (in_array($key, $this->protectedProperties)) {
+            throw new Exception\InvalidArgumentException('$key is a protected property, use a different key');
+        }
+
+        return $this->$key;
+    }
+
+    /**
+     * Appends the value
+     *
+     * @param  mixed $value
+     * @return void
+     */
+    public function append($value)
+    {
+        $this->storage[] = $value;
+    }
+
+    /**
+     * Sort the entries by value
+     *
+     * @return void
+     */
+    public function asort()
+    {
+        asort($this->storage);
+    }
+
+    /**
+     * Get the number of public properties in the ArrayObject
+     *
+     * @return int
+     */
+    public function count()
+    {
+        return count($this->storage);
+    }
+
+    /**
+     * Exchange the array for another one.
+     *
+     * @param  array|ArrayObject $data
+     * @return array
+     */
+    public function exchangeArray($data)
+    {
+        if (!is_array($data) && !is_object($data)) {
+            throw new Exception\InvalidArgumentException('Passed variable is not an array or object, using empty array instead');
+        }
+
+        if (is_object($data) && ($data instanceof self || $data instanceof \ArrayObject)) {
+            $data = $data->getArrayCopy();
+        }
+        if (!is_array($data)) {
+            $data = (array) $data;
+        }
+
+        $storage = $this->storage;
+
+        $this->storage = $data;
+
+        return $storage;
+    }
+
+    /**
+     * Creates a copy of the ArrayObject.
+     *
+     * @return array
+     */
+    public function getArrayCopy()
+    {
+        return $this->storage;
+    }
+
+    /**
+     * Gets the behavior flags.
+     *
+     * @return int
+     */
+    public function getFlags()
+    {
+        return $this->flag;
+    }
+
+    /**
+     * Create a new iterator from an ArrayObject instance
+     *
+     * @return \Iterator
+     */
+    public function getIterator()
+    {
+        $class = $this->iteratorClass;
+
+        return new $class($this->storage);
+    }
+
+    /**
+     * Gets the iterator classname for the ArrayObject.
+     *
+     * @return string
+     */
+    public function getIteratorClass()
+    {
+        return $this->iteratorClass;
+    }
+
+    /**
+     * Sort the entries by key
+     *
+     * @return void
+     */
+    public function ksort()
+    {
+        ksort($this->storage);
+    }
+
+    /**
+     * Sort an array using a case insensitive "natural order" algorithm
+     *
+     * @return void
+     */
+    public function natcasesort()
+    {
+        natcasesort($this->storage);
+    }
+
+    /**
+     * Sort entries using a "natural order" algorithm
+     *
+     * @return void
+     */
+    public function natsort()
+    {
+        natsort($this->storage);
+    }
+
+    /**
+     * Returns whether the requested key exists
+     *
+     * @param  mixed $key
+     * @return bool
+     */
+    public function offsetExists($key)
+    {
+        return isset($this->storage[$key]);
+    }
+
+    /**
+     * Returns the value at the specified key
+     *
+     * @param  mixed $key
+     * @return mixed
+     */
+    public function &offsetGet($key)
+    {
+        $ret = null;
+        if (!$this->offsetExists($key)) {
+            return $ret;
+        }
+        $ret =& $this->storage[$key];
+
+        return $ret;
+    }
+
+    /**
+     * Sets the value at the specified key to value
+     *
+     * @param  mixed $key
+     * @param  mixed $value
+     * @return void
+     */
+    public function offsetSet($key, $value)
+    {
+        $this->storage[$key] = $value;
+    }
+
+    /**
+     * Unsets the value at the specified key
+     *
+     * @param  mixed $key
+     * @return void
+     */
+    public function offsetUnset($key)
+    {
+        if ($this->offsetExists($key)) {
+            unset($this->storage[$key]);
+        }
+    }
+
+    /**
+     * Serialize an ArrayObject
+     *
+     * @return string
+     */
+    public function serialize()
+    {
+        return serialize(get_object_vars($this));
+    }
+
+    /**
+     * Sets the behavior flags
+     *
+     * @param  int  $flags
+     * @return void
+     */
+    public function setFlags($flags)
+    {
+        $this->flag = $flags;
+    }
+
+    /**
+     * Sets the iterator classname for the ArrayObject
+     *
+     * @param  string $class
+     * @return void
+     */
+    public function setIteratorClass($class)
+    {
+        if (class_exists($class)) {
+            $this->iteratorClass = $class;
+
+            return ;
+        }
+
+        if (strpos($class, '\\') === 0) {
+            $class = '\\' . $class;
+            if (class_exists($class)) {
+                $this->iteratorClass = $class;
+
+                return ;
+            }
+        }
+
+        throw new Exception\InvalidArgumentException('The iterator class does not exist');
+    }
+
+    /**
+     * Sort the entries with a user-defined comparison function and maintain key association
+     *
+     * @param  callable $function
+     * @return void
+     */
+    public function uasort($function)
+    {
+        if (is_callable($function)) {
+            uasort($this->storage, $function);
+        }
+    }
+
+    /**
+     * Sort the entries by keys using a user-defined comparison function
+     *
+     * @param  callable $function
+     * @return void
+     */
+    public function uksort($function)
+    {
+        if (is_callable($function)) {
+            uksort($this->storage, $function);
+        }
+    }
+
+    /**
+     * Unserialize an ArrayObject
+     *
+     * @param  string $data
+     * @return void
+     */
+    public function unserialize($data)
+    {
+        $ar = unserialize($data);
+        $this->setFlags($ar['flag']);
+        $this->exchangeArray($ar['storage']);
+        $this->setIteratorClass($ar['iteratorClass']);
+        foreach ($ar as $k => $v) {
+            switch ($k) {
+                case 'flag':
+                    $this->setFlags($v);
+                    break;
+                case 'storage':
+                    $this->exchangeArray($v);
+                    break;
+                case 'iteratorClass':
+                    $this->setIteratorClass($v);
+                    break;
+                case 'protectedProperties':
+                    continue;
+                default:
+                    $this->__set($k, $v);
+            }
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ArraySerializableInterface.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ArraySerializableInterface.php
new file mode 100644
index 000000000000..7bd6f6eddb54
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ArraySerializableInterface.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+interface ArraySerializableInterface
+{
+    /**
+     * Exchange internal values from provided array
+     *
+     * @param  array $array
+     * @return void
+     */
+    public function exchangeArray(array $array);
+
+    /**
+     * Return an array representation of the object
+     *
+     * @return array
+     */
+    public function getArrayCopy();
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ArrayStack.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ArrayStack.php
new file mode 100644
index 000000000000..559d65e3f0a6
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ArrayStack.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+use ArrayIterator;
+use ArrayObject as PhpArrayObject;
+
+/**
+ * ArrayObject that acts as a stack with regards to iteration
+ */
+class ArrayStack extends PhpArrayObject
+{
+    /**
+     * Retrieve iterator
+     *
+     * Retrieve an array copy of the object, reverse its order, and return an
+     * ArrayIterator with that reversed array.
+     *
+     * @return ArrayIterator
+     */
+    public function getIterator()
+    {
+        $array = $this->getArrayCopy();
+        return new ArrayIterator(array_reverse($array));
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ArrayUtils.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ArrayUtils.php
new file mode 100644
index 000000000000..4261d2e65fa9
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ArrayUtils.php
@@ -0,0 +1,275 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+use Traversable;
+
+/**
+ * Utility class for testing and manipulation of PHP arrays.
+ *
+ * Declared abstract, as we have no need for instantiation.
+ */
+abstract class ArrayUtils
+{
+    /**
+     * Test whether an array contains one or more string keys
+     *
+     * @param  mixed $value
+     * @param  bool  $allowEmpty    Should an empty array() return true
+     * @return bool
+     */
+    public static function hasStringKeys($value, $allowEmpty = false)
+    {
+        if (!is_array($value)) {
+            return false;
+        }
+
+        if (!$value) {
+            return $allowEmpty;
+        }
+
+        return count(array_filter(array_keys($value), 'is_string')) > 0;
+    }
+
+    /**
+     * Test whether an array contains one or more integer keys
+     *
+     * @param  mixed $value
+     * @param  bool  $allowEmpty    Should an empty array() return true
+     * @return bool
+     */
+    public static function hasIntegerKeys($value, $allowEmpty = false)
+    {
+        if (!is_array($value)) {
+            return false;
+        }
+
+        if (!$value) {
+            return $allowEmpty;
+        }
+
+        return count(array_filter(array_keys($value), 'is_int')) > 0;
+    }
+
+    /**
+     * Test whether an array contains one or more numeric keys.
+     *
+     * A numeric key can be one of the following:
+     * - an integer 1,
+     * - a string with a number '20'
+     * - a string with negative number: '-1000'
+     * - a float: 2.2120, -78.150999
+     * - a string with float:  '4000.99999', '-10.10'
+     *
+     * @param  mixed $value
+     * @param  bool  $allowEmpty    Should an empty array() return true
+     * @return bool
+     */
+    public static function hasNumericKeys($value, $allowEmpty = false)
+    {
+        if (!is_array($value)) {
+            return false;
+        }
+
+        if (!$value) {
+            return $allowEmpty;
+        }
+
+        return count(array_filter(array_keys($value), 'is_numeric')) > 0;
+    }
+
+    /**
+     * Test whether an array is a list
+     *
+     * A list is a collection of values assigned to continuous integer keys
+     * starting at 0 and ending at count() - 1.
+     *
+     * For example:
+     * <code>
+     * $list = array('a', 'b', 'c', 'd');
+     * $list = array(
+     *     0 => 'foo',
+     *     1 => 'bar',
+     *     2 => array('foo' => 'baz'),
+     * );
+     * </code>
+     *
+     * @param  mixed $value
+     * @param  bool  $allowEmpty    Is an empty list a valid list?
+     * @return bool
+     */
+    public static function isList($value, $allowEmpty = false)
+    {
+        if (!is_array($value)) {
+            return false;
+        }
+
+        if (!$value) {
+            return $allowEmpty;
+        }
+
+        return (array_values($value) === $value);
+    }
+
+    /**
+     * Test whether an array is a hash table.
+     *
+     * An array is a hash table if:
+     *
+     * 1. Contains one or more non-integer keys, or
+     * 2. Integer keys are non-continuous or misaligned (not starting with 0)
+     *
+     * For example:
+     * <code>
+     * $hash = array(
+     *     'foo' => 15,
+     *     'bar' => false,
+     * );
+     * $hash = array(
+     *     1995  => 'Birth of PHP',
+     *     2009  => 'PHP 5.3.0',
+     *     2012  => 'PHP 5.4.0',
+     * );
+     * $hash = array(
+     *     'formElement,
+     *     'options' => array( 'debug' => true ),
+     * );
+     * </code>
+     *
+     * @param  mixed $value
+     * @param  bool  $allowEmpty    Is an empty array() a valid hash table?
+     * @return bool
+     */
+    public static function isHashTable($value, $allowEmpty = false)
+    {
+        if (!is_array($value)) {
+            return false;
+        }
+
+        if (!$value) {
+            return $allowEmpty;
+        }
+
+        return (array_values($value) !== $value);
+    }
+
+    /**
+     * Checks if a value exists in an array.
+     *
+     * Due to "foo" == 0 === TRUE with in_array when strict = false, an option
+     * has been added to prevent this. When $strict = 0/false, the most secure
+     * non-strict check is implemented. if $strict = -1, the default in_array
+     * non-strict behaviour is used.
+     *
+     * @param mixed $needle
+     * @param array $haystack
+     * @param int|bool $strict
+     * @return bool
+     */
+    public static function inArray($needle, array $haystack, $strict = false)
+    {
+        if (!$strict) {
+            if (is_int($needle) || is_float($needle)) {
+                $needle = (string) $needle;
+            }
+            if (is_string($needle)) {
+                foreach ($haystack as &$h) {
+                    if (is_int($h) || is_float($h)) {
+                        $h = (string) $h;
+                    }
+                }
+            }
+        }
+        return in_array($needle, $haystack, $strict);
+    }
+
+    /**
+     * Convert an iterator to an array.
+     *
+     * Converts an iterator to an array. The $recursive flag, on by default,
+     * hints whether or not you want to do so recursively.
+     *
+     * @param  array|Traversable  $iterator     The array or Traversable object to convert
+     * @param  bool               $recursive    Recursively check all nested structures
+     * @throws Exception\InvalidArgumentException if $iterator is not an array or a Traversable object
+     * @return array
+     */
+    public static function iteratorToArray($iterator, $recursive = true)
+    {
+        if (!is_array($iterator) && !$iterator instanceof Traversable) {
+            throw new Exception\InvalidArgumentException(__METHOD__ . ' expects an array or Traversable object');
+        }
+
+        if (!$recursive) {
+            if (is_array($iterator)) {
+                return $iterator;
+            }
+
+            return iterator_to_array($iterator);
+        }
+
+        if (method_exists($iterator, 'toArray')) {
+            return $iterator->toArray();
+        }
+
+        $array = array();
+        foreach ($iterator as $key => $value) {
+            if (is_scalar($value)) {
+                $array[$key] = $value;
+                continue;
+            }
+
+            if ($value instanceof Traversable) {
+                $array[$key] = static::iteratorToArray($value, $recursive);
+                continue;
+            }
+
+            if (is_array($value)) {
+                $array[$key] = static::iteratorToArray($value, $recursive);
+                continue;
+            }
+
+            $array[$key] = $value;
+        }
+
+        return $array;
+    }
+
+    /**
+     * Merge two arrays together.
+     *
+     * If an integer key exists in both arrays, the value from the second array
+     * will be appended the the first array. If both values are arrays, they
+     * are merged together, else the value of the second array overwrites the
+     * one of the first array.
+     *
+     * @param  array $a
+     * @param  array $b
+     * @return array
+     */
+    public static function merge(array $a, array $b)
+    {
+        foreach ($b as $key => $value) {
+            if (array_key_exists($key, $a)) {
+                if (is_int($key)) {
+                    $a[] = $value;
+                } elseif (is_array($value) && is_array($a[$key])) {
+                    $a[$key] = static::merge($a[$key], $value);
+                } else {
+                    $a[$key] = $value;
+                }
+            } else {
+                $a[$key] = $value;
+            }
+        }
+
+        return $a;
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/CallbackHandler.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/CallbackHandler.php
new file mode 100644
index 000000000000..f1ac4a65b36d
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/CallbackHandler.php
@@ -0,0 +1,218 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+use Closure;
+use ReflectionClass;
+
+/**
+ * CallbackHandler
+ *
+ * A handler for a event, event, filterchain, etc. Abstracts PHP callbacks,
+ * primarily to allow for lazy-loading and ensuring availability of default
+ * arguments (currying).
+ */
+class CallbackHandler
+{
+    /**
+     * @var string|array|callable PHP callback to invoke
+     */
+    protected $callback;
+
+    /**
+     * Callback metadata, if any
+     * @var array
+     */
+    protected $metadata;
+
+    /**
+     * PHP version is greater as 5.4rc1?
+     * @var bool
+     */
+    protected static $isPhp54;
+
+    /**
+     * Constructor
+     *
+     * @param  string|array|object|callable $callback PHP callback
+     * @param  array                        $metadata  Callback metadata
+     */
+    public function __construct($callback, array $metadata = array())
+    {
+        $this->metadata  = $metadata;
+        $this->registerCallback($callback);
+    }
+
+    /**
+     * Registers the callback provided in the constructor
+     *
+     * @param  callable $callback
+     * @throws Exception\InvalidCallbackException
+     * @return void
+     */
+    protected function registerCallback($callback)
+    {
+        if (!is_callable($callback)) {
+            throw new Exception\InvalidCallbackException('Invalid callback provided; not callable');
+        }
+
+        $this->callback = $callback;
+    }
+
+    /**
+     * Retrieve registered callback
+     *
+     * @return callable
+     */
+    public function getCallback()
+    {
+        return $this->callback;
+    }
+
+    /**
+     * Invoke handler
+     *
+     * @param  array $args Arguments to pass to callback
+     * @return mixed
+     */
+    public function call(array $args = array())
+    {
+        $callback = $this->getCallback();
+
+        // Minor performance tweak, if the callback gets called more than once
+        if (!isset(static::$isPhp54)) {
+            static::$isPhp54 = version_compare(PHP_VERSION, '5.4.0rc1', '>=');
+        }
+
+        $argCount = count($args);
+
+        if (static::$isPhp54 && is_string($callback)) {
+            $result = $this->validateStringCallbackFor54($callback);
+
+            if ($result !== true && $argCount <= 3) {
+                $callback       = $result;
+                // Minor performance tweak, if the callback gets called more
+                // than once
+                $this->callback = $result;
+            }
+        }
+
+        // Minor performance tweak; use call_user_func() until > 3 arguments
+        // reached
+        switch ($argCount) {
+            case 0:
+                if (static::$isPhp54) {
+                    return $callback();
+                }
+                return call_user_func($callback);
+            case 1:
+                if (static::$isPhp54) {
+                    return $callback(array_shift($args));
+                }
+                return call_user_func($callback, array_shift($args));
+            case 2:
+                $arg1 = array_shift($args);
+                $arg2 = array_shift($args);
+                if (static::$isPhp54) {
+                    return $callback($arg1, $arg2);
+                }
+                return call_user_func($callback, $arg1, $arg2);
+            case 3:
+                $arg1 = array_shift($args);
+                $arg2 = array_shift($args);
+                $arg3 = array_shift($args);
+                if (static::$isPhp54) {
+                    return $callback($arg1, $arg2, $arg3);
+                }
+                return call_user_func($callback, $arg1, $arg2, $arg3);
+            default:
+                return call_user_func_array($callback, $args);
+        }
+    }
+
+    /**
+     * Invoke as functor
+     *
+     * @return mixed
+     */
+    public function __invoke()
+    {
+        return $this->call(func_get_args());
+    }
+
+    /**
+     * Get all callback metadata
+     *
+     * @return array
+     */
+    public function getMetadata()
+    {
+        return $this->metadata;
+    }
+
+    /**
+     * Retrieve a single metadatum
+     *
+     * @param  string $name
+     * @return mixed
+     */
+    public function getMetadatum($name)
+    {
+        if (array_key_exists($name, $this->metadata)) {
+            return $this->metadata[$name];
+        }
+        return null;
+    }
+
+    /**
+     * Validate a static method call
+     *
+     * Validates that a static method call in PHP 5.4 will actually work
+     *
+     * @param  string $callback
+     * @return true|array
+     * @throws Exception\InvalidCallbackException if invalid
+     */
+    protected function validateStringCallbackFor54($callback)
+    {
+        if (!strstr($callback, '::')) {
+            return true;
+        }
+
+        list($class, $method) = explode('::', $callback, 2);
+
+        if (!class_exists($class)) {
+            throw new Exception\InvalidCallbackException(sprintf(
+                'Static method call "%s" refers to a class that does not exist',
+                $callback
+            ));
+        }
+
+        $r = new ReflectionClass($class);
+        if (!$r->hasMethod($method)) {
+            throw new Exception\InvalidCallbackException(sprintf(
+                'Static method call "%s" refers to a method that does not exist',
+                $callback
+            ));
+        }
+        $m = $r->getMethod($method);
+        if (!$m->isStatic()) {
+            throw new Exception\InvalidCallbackException(sprintf(
+                'Static method call "%s" refers to a method that is not static',
+                $callback
+            ));
+        }
+
+        // returning a non boolean value may not be nice for a validate method,
+        // but that allows the usage of a static string callback without using
+        // the call_user_func function.
+        return array($class, $method);
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/DateTime.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/DateTime.php
new file mode 100644
index 000000000000..5c88ad4732cd
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/DateTime.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+use DateTimeZone;
+
+trigger_error('DateTime extension deprecated as of ZF 2.1.4; use the \DateTime constructor to parse extended ISO8601 dates instead', E_USER_DEPRECATED);
+
+/**
+ * DateTime
+ *
+ * An extension of the \DateTime object.
+ *
+ * @deprecated
+ */
+class DateTime extends \DateTime
+{
+    /**
+     * The DateTime::ISO8601 constant used by php's native DateTime object does
+     * not allow for fractions of a second. This function better handles ISO8601
+     * formatted date strings.
+     *
+     * @param  string       $time
+     * @param  DateTimeZone $timezone
+     * @return mixed
+     */
+    public static function createFromISO8601($time, DateTimeZone $timezone = null)
+    {
+        $format = self::ISO8601;
+        if (isset($time[19]) && $time[19] === '.') {
+            $format = 'Y-m-d\TH:i:s.uO';
+        }
+
+        if ($timezone !== null) {
+            return self::createFromFormat($format, $time, $timezone);
+        }
+
+        return self::createFromFormat($format, $time);
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/DispatchableInterface.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/DispatchableInterface.php
new file mode 100644
index 000000000000..ab672fa13f8e
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/DispatchableInterface.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+use Zend\Stdlib\RequestInterface as Request;
+use Zend\Stdlib\ResponseInterface as Response;
+
+interface DispatchableInterface
+{
+    /**
+     * Dispatch a request
+     *
+     * @param Request $request
+     * @param null|Response $response
+     * @return Response|mixed
+     */
+    public function dispatch(Request $request, Response $response = null);
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ErrorHandler.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ErrorHandler.php
new file mode 100644
index 000000000000..5096f53d9d32
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ErrorHandler.php
@@ -0,0 +1,115 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+use ErrorException;
+
+/**
+ * ErrorHandler that can be used to catch internal PHP errors
+ * and convert to a ErrorException instance.
+ */
+abstract class ErrorHandler
+{
+    /**
+     * Active stack
+     *
+     * @var array
+     */
+    protected static $stack = array();
+
+    /**
+     * Check if this error handler is active
+     *
+     * @return bool
+     */
+    public static function started()
+    {
+        return (bool) static::getNestedLevel();
+    }
+
+    /**
+     * Get the current nested level
+     *
+     * @return int
+     */
+    public static function getNestedLevel()
+    {
+        return count(static::$stack);
+    }
+
+    /**
+     * Starting the error handler
+     *
+     * @param int $errorLevel
+     */
+    public static function start($errorLevel = \E_WARNING)
+    {
+        if (!static::$stack) {
+            set_error_handler(array(get_called_class(), 'addError'), $errorLevel);
+        }
+
+        static::$stack[] = null;
+    }
+
+    /**
+     * Stopping the error handler
+     *
+     * @param  bool $throw Throw the ErrorException if any
+     * @return null|ErrorException
+     * @throws ErrorException If an error has been catched and $throw is true
+     */
+    public static function stop($throw = false)
+    {
+        $errorException = null;
+
+        if (static::$stack) {
+            $errorException = array_pop(static::$stack);
+
+            if (!static::$stack) {
+                restore_error_handler();
+            }
+
+            if ($errorException && $throw) {
+                throw $errorException;
+            }
+        }
+
+        return $errorException;
+    }
+
+    /**
+     * Stop all active handler
+     *
+     * @return void
+     */
+    public static function clean()
+    {
+        if (static::$stack) {
+            restore_error_handler();
+        }
+
+        static::$stack = array();
+    }
+
+    /**
+     * Add an error to the stack
+     *
+     * @param int    $errno
+     * @param string $errstr
+     * @param string $errfile
+     * @param int    $errline
+     * @return void
+     */
+    public static function addError($errno, $errstr = '', $errfile = '', $errline = 0)
+    {
+        $stack = & static::$stack[count(static::$stack) - 1];
+        $stack = new ErrorException($errstr, 0, $errno, $errfile, $errline, $stack);
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/BadMethodCallException.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/BadMethodCallException.php
new file mode 100644
index 000000000000..6cf1c9ecc077
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/BadMethodCallException.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Exception;
+
+/**
+ * Bad method call exception
+ */
+class BadMethodCallException extends \BadMethodCallException implements ExceptionInterface
+{
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/DomainException.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/DomainException.php
new file mode 100644
index 000000000000..2744570f28f9
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/DomainException.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Exception;
+
+/**
+ * Domain exception
+ */
+class DomainException extends \DomainException implements ExceptionInterface
+{
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/ExceptionInterface.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/ExceptionInterface.php
new file mode 100644
index 000000000000..0424a4ea9a87
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/ExceptionInterface.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Exception;
+
+/**
+ * Exception marker interface
+ */
+interface ExceptionInterface
+{
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/ExtensionNotLoadedException.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/ExtensionNotLoadedException.php
new file mode 100644
index 000000000000..b883641a63da
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/ExtensionNotLoadedException.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Exception;
+
+/**
+ * Extension not loaded exception
+ */
+class ExtensionNotLoadedException extends RuntimeException
+{
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/InvalidArgumentException.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/InvalidArgumentException.php
new file mode 100644
index 000000000000..9efb0e09b5a5
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/InvalidArgumentException.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Exception;
+
+/**
+ * Invalid Argument Exception
+ */
+class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/InvalidCallbackException.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/InvalidCallbackException.php
new file mode 100644
index 000000000000..30e97e83bda4
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/InvalidCallbackException.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Exception;
+
+/**
+ * Invalid callback exception
+ */
+class InvalidCallbackException extends DomainException implements ExceptionInterface
+{
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/LogicException.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/LogicException.php
new file mode 100644
index 000000000000..55e07d6a9775
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/LogicException.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Exception;
+
+/**
+ * Logic exception
+ */
+class LogicException extends \LogicException implements ExceptionInterface
+{
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/RuntimeException.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/RuntimeException.php
new file mode 100644
index 000000000000..20c065587d23
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Exception/RuntimeException.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Exception;
+
+/**
+ * Runtime exception
+ */
+class RuntimeException extends \RuntimeException implements ExceptionInterface
+{
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Glob.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Glob.php
new file mode 100644
index 000000000000..a9e29fd0c680
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Glob.php
@@ -0,0 +1,205 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+use Zend\Stdlib\Exception;
+use Zend\Stdlib\ErrorHandler;
+
+/**
+ * Wrapper for glob with fallback if GLOB_BRACE is not available.
+ */
+abstract class Glob
+{
+    /**#@+
+     * Glob constants.
+     */
+    const GLOB_MARK     = 0x01;
+    const GLOB_NOSORT   = 0x02;
+    const GLOB_NOCHECK  = 0x04;
+    const GLOB_NOESCAPE = 0x08;
+    const GLOB_BRACE    = 0x10;
+    const GLOB_ONLYDIR  = 0x20;
+    const GLOB_ERR      = 0x40;
+    /**#@-*/
+
+    /**
+     * Find pathnames matching a pattern.
+     *
+     * @see    http://docs.php.net/glob
+     * @param  string  $pattern
+     * @param  int $flags
+     * @param  bool $forceFallback
+     * @return array
+     * @throws Exception\RuntimeException
+     */
+    public static function glob($pattern, $flags = 0, $forceFallback = false)
+    {
+        if (!defined('GLOB_BRACE') || $forceFallback) {
+            return static::fallbackGlob($pattern, $flags);
+        }
+
+        return static::systemGlob($pattern, $flags);
+    }
+
+    /**
+     * Use the glob function provided by the system.
+     *
+     * @param  string  $pattern
+     * @param  int     $flags
+     * @return array
+     * @throws Exception\RuntimeException
+     */
+    protected static function systemGlob($pattern, $flags)
+    {
+        if ($flags) {
+            $flagMap = array(
+                self::GLOB_MARK     => GLOB_MARK,
+                self::GLOB_NOSORT   => GLOB_NOSORT,
+                self::GLOB_NOCHECK  => GLOB_NOCHECK,
+                self::GLOB_NOESCAPE => GLOB_NOESCAPE,
+                self::GLOB_BRACE    => GLOB_BRACE,
+                self::GLOB_ONLYDIR  => GLOB_ONLYDIR,
+                self::GLOB_ERR      => GLOB_ERR,
+            );
+
+            $globFlags = 0;
+
+            foreach ($flagMap as $internalFlag => $globFlag) {
+                if ($flags & $internalFlag) {
+                    $globFlags |= $globFlag;
+                }
+            }
+        } else {
+            $globFlags = 0;
+        }
+
+        ErrorHandler::start();
+        $res = glob($pattern, $globFlags);
+        $err = ErrorHandler::stop();
+        if ($res === false) {
+            throw new Exception\RuntimeException("glob('{$pattern}', {$globFlags}) failed", 0, $err);
+        }
+        return $res;
+    }
+
+    /**
+     * Expand braces manually, then use the system glob.
+     *
+     * @param  string  $pattern
+     * @param  int     $flags
+     * @return array
+     * @throws Exception\RuntimeException
+     */
+    protected static function fallbackGlob($pattern, $flags)
+    {
+        if (!$flags & self::GLOB_BRACE) {
+            return static::systemGlob($pattern, $flags);
+        }
+
+        $flags &= ~self::GLOB_BRACE;
+        $length = strlen($pattern);
+        $paths  = array();
+
+        if ($flags & self::GLOB_NOESCAPE) {
+            $begin = strpos($pattern, '{');
+        } else {
+            $begin = 0;
+
+            while (true) {
+                if ($begin === $length) {
+                    $begin = false;
+                    break;
+                } elseif ($pattern[$begin] === '\\' && ($begin + 1) < $length) {
+                    $begin++;
+                } elseif ($pattern[$begin] === '{') {
+                    break;
+                }
+
+                $begin++;
+            }
+        }
+
+        if ($begin === false) {
+            return static::systemGlob($pattern, $flags);
+        }
+
+        $next = static::nextBraceSub($pattern, $begin + 1, $flags);
+
+        if ($next === null) {
+            return static::systemGlob($pattern, $flags);
+        }
+
+        $rest = $next;
+
+        while ($pattern[$rest] !== '}') {
+            $rest = static::nextBraceSub($pattern, $rest + 1, $flags);
+
+            if ($rest === null) {
+                return static::systemGlob($pattern, $flags);
+            }
+        }
+
+        $p = $begin + 1;
+
+        while (true) {
+            $subPattern = substr($pattern, 0, $begin)
+                        . substr($pattern, $p, $next - $p)
+                        . substr($pattern, $rest + 1);
+
+            $result = static::fallbackGlob($subPattern, $flags | self::GLOB_BRACE);
+
+            if ($result) {
+                $paths = array_merge($paths, $result);
+            }
+
+            if ($pattern[$next] === '}') {
+                break;
+            }
+
+            $p    = $next + 1;
+            $next = static::nextBraceSub($pattern, $p, $flags);
+        }
+
+        return array_unique($paths);
+    }
+
+    /**
+     * Find the end of the sub-pattern in a brace expression.
+     *
+     * @param  string  $pattern
+     * @param  int $begin
+     * @param  int $flags
+     * @return int|null
+     */
+    protected static function nextBraceSub($pattern, $begin, $flags)
+    {
+        $length  = strlen($pattern);
+        $depth   = 0;
+        $current = $begin;
+
+        while ($current < $length) {
+            if (!$flags & self::GLOB_NOESCAPE && $pattern[$current] === '\\') {
+                if (++$current === $length) {
+                    break;
+                }
+
+                $current++;
+            } else {
+                if (($pattern[$current] === '}' && $depth-- === 0) || ($pattern[$current] === ',' && $depth === 0)) {
+                    break;
+                } elseif ($pattern[$current++] === '{') {
+                    $depth++;
+                }
+            }
+        }
+
+        return ($current < $length ? $current : null);
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/AbstractHydrator.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/AbstractHydrator.php
new file mode 100644
index 000000000000..4cb9a4356f72
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/AbstractHydrator.php
@@ -0,0 +1,198 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Hydrator;
+
+use ArrayObject;
+use Zend\Stdlib\Exception;
+use Zend\Stdlib\Hydrator\Filter\FilterComposite;
+use Zend\Stdlib\Hydrator\StrategyEnabledInterface;
+use Zend\Stdlib\Hydrator\Strategy\StrategyInterface;
+
+abstract class AbstractHydrator implements HydratorInterface, StrategyEnabledInterface
+{
+    /**
+     * The list with strategies that this hydrator has.
+     *
+     * @var ArrayObject
+     */
+    protected $strategies;
+
+    /**
+     * Composite to filter the methods, that need to be hydrated
+     * @var Filter\FilterComposite
+     */
+    protected $filterComposite;
+
+    /**
+     * Initializes a new instance of this class.
+     */
+    public function __construct()
+    {
+        $this->strategies = new ArrayObject();
+        $this->filterComposite = new FilterComposite();
+    }
+
+    /**
+     * Gets the strategy with the given name.
+     *
+     * @param string $name The name of the strategy to get.
+     * @return StrategyInterface
+     */
+    public function getStrategy($name)
+    {
+        if (isset($this->strategies[$name])) {
+            return $this->strategies[$name];
+        }
+
+        if (!isset($this->strategies['*'])) {
+            throw new Exception\InvalidArgumentException(sprintf(
+                '%s: no strategy by name of "%s", and no wildcard strategy present',
+                __METHOD__,
+                $name
+            ));
+        }
+
+        return $this->strategies['*'];
+    }
+
+    /**
+     * Checks if the strategy with the given name exists.
+     *
+     * @param string $name The name of the strategy to check for.
+     * @return bool
+     */
+    public function hasStrategy($name)
+    {
+        return array_key_exists($name, $this->strategies)
+               || array_key_exists('*', $this->strategies);
+    }
+
+    /**
+     * Adds the given strategy under the given name.
+     *
+     * @param string $name The name of the strategy to register.
+     * @param StrategyInterface $strategy The strategy to register.
+     * @return HydratorInterface
+     */
+    public function addStrategy($name, StrategyInterface $strategy)
+    {
+        $this->strategies[$name] = $strategy;
+        return $this;
+    }
+
+    /**
+     * Removes the strategy with the given name.
+     *
+     * @param string $name The name of the strategy to remove.
+     * @return HydratorInterface
+     */
+    public function removeStrategy($name)
+    {
+        unset($this->strategies[$name]);
+        return $this;
+    }
+
+    /**
+     * Converts a value for extraction. If no strategy exists the plain value is returned.
+     *
+     * @param  string $name  The name of the strategy to use.
+     * @param  mixed  $value  The value that should be converted.
+     * @param  array  $object The object is optionally provided as context.
+     * @return mixed
+     */
+    public function extractValue($name, $value, $object = null)
+    {
+        if ($this->hasStrategy($name)) {
+            $strategy = $this->getStrategy($name);
+            $value = $strategy->extract($value, $object);
+        }
+        return $value;
+    }
+
+    /**
+     * Converts a value for hydration. If no strategy exists the plain value is returned.
+     *
+     * @param string $name The name of the strategy to use.
+     * @param mixed $value The value that should be converted.
+     * @param array $data The whole data is optionally provided as context.
+     * @return mixed
+     */
+    public function hydrateValue($name, $value, $data = null)
+    {
+        if ($this->hasStrategy($name)) {
+            $strategy = $this->getStrategy($name);
+            $value = $strategy->hydrate($value, $data);
+        }
+        return $value;
+    }
+
+    /**
+     * Get the filter instance
+     *
+     * @return Filter\FilterComposite
+     */
+    public function getFilter()
+    {
+        return $this->filterComposite;
+    }
+
+    /**
+     * Add a new filter to take care of what needs to be hydrated.
+     * To exclude e.g. the method getServiceLocator:
+     *
+     * <code>
+     * $composite->addFilter("servicelocator",
+     *     function($property) {
+     *         list($class, $method) = explode('::', $property);
+     *         if ($method === 'getServiceLocator') {
+     *             return false;
+     *         }
+     *         return true;
+     *     }, FilterComposite::CONDITION_AND
+     * );
+     * </code>
+     *
+     * @param string $name Index in the composite
+     * @param callable|Filter\FilterInterface $filter
+     * @param int $condition
+     * @return Filter\FilterComposite
+     */
+    public function addFilter($name, $filter, $condition = FilterComposite::CONDITION_OR)
+    {
+        return $this->filterComposite->addFilter($name, $filter, $condition);
+    }
+
+    /**
+     * Check whether a specific filter exists at key $name or not
+     *
+     * @param string $name Index in the composite
+     * @return bool
+     */
+    public function hasFilter($name)
+    {
+        return $this->filterComposite->hasFilter($name);
+    }
+
+    /**
+     * Remove a filter from the composition.
+     * To not extract "has" methods, you simply need to unregister it
+     *
+     * <code>
+     * $filterComposite->removeFilter('has');
+     * </code>
+     *
+     * @param $name
+     * @return Filter\FilterComposite
+     */
+    public function removeFilter($name)
+    {
+        return $this->filterComposite->removeFilter($name);
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Aggregate/AggregateHydrator.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Aggregate/AggregateHydrator.php
new file mode 100644
index 000000000000..bdcf1eb0adfd
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Aggregate/AggregateHydrator.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Hydrator\Aggregate;
+
+use Zend\EventManager\EventManager;
+use Zend\EventManager\EventManagerAwareInterface;
+use Zend\EventManager\EventManagerInterface;
+use Zend\Stdlib\Exception;
+use Zend\Stdlib\Hydrator\Filter\FilterComposite;
+use Zend\Stdlib\Hydrator\HydratorInterface;
+
+/**
+ * Aggregate hydrator that composes multiple hydrators via events
+ */
+class AggregateHydrator implements HydratorInterface, EventManagerAwareInterface
+{
+    const DEFAULT_PRIORITY = 1;
+
+    /**
+     * @var \Zend\EventManager\EventManagerInterface|null
+     */
+    protected $eventManager;
+
+    /**
+     * Attaches the provided hydrator to the list of hydrators to be used while hydrating/extracting data
+     *
+     * @param \Zend\Stdlib\Hydrator\HydratorInterface $hydrator
+     * @param int                                     $priority
+     */
+    public function add(HydratorInterface $hydrator, $priority = self::DEFAULT_PRIORITY)
+    {
+        $this->getEventManager()->attachAggregate(new HydratorListener($hydrator), $priority);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function extract($object)
+    {
+        $event = new ExtractEvent($this, $object);
+
+        $this->getEventManager()->trigger($event);
+
+        return $event->getExtractedData();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function hydrate(array $data, $object)
+    {
+        $event = new HydrateEvent($this, $object, $data);
+
+        $this->getEventManager()->trigger($event);
+
+        return $event->getHydratedObject();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setEventManager(EventManagerInterface $eventManager)
+    {
+        $eventManager->setIdentifiers(array(__CLASS__, get_class($this)));
+
+        $this->eventManager = $eventManager;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getEventManager()
+    {
+        if (null === $this->eventManager) {
+            $this->setEventManager(new EventManager());
+        }
+
+        return $this->eventManager;
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Aggregate/ExtractEvent.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Aggregate/ExtractEvent.php
new file mode 100644
index 000000000000..dfdfbcfb6b50
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Aggregate/ExtractEvent.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Hydrator\Aggregate;
+
+
+use Zend\EventManager\Event;
+
+/**
+ * Event triggered when the {@see \Zend\Stdlib\Hydrator\Aggregate\AggregateHydrator} extracts
+ * data from an object
+ */
+class ExtractEvent extends Event
+{
+    const EVENT_EXTRACT = 'extract';
+
+    /**
+     * {@inheritDoc}
+     */
+    protected $name = self::EVENT_EXTRACT;
+
+    /**
+     * @var object
+     */
+    protected $extractionObject;
+
+    /**
+     * @var array
+     */
+    protected $extractedData = array();
+
+    /**
+     * @param object $target
+     * @param object $extractionObject
+     */
+    public function __construct($target, $extractionObject)
+    {
+        $this->target           = $target;
+        $this->extractionObject = $extractionObject;
+    }
+
+    /**
+     * Retrieves the object from which data is extracted
+     *
+     * @return object
+     */
+    public function getExtractionObject()
+    {
+        return $this->extractionObject;
+    }
+
+    /**
+     * @param object $extractionObject
+     *
+     * @return void
+     */
+    public function setExtractionObject($extractionObject)
+    {
+        $this->extractionObject = $extractionObject;
+    }
+
+    /**
+     * Retrieves the data that has been extracted
+     *
+     * @return array
+     */
+    public function getExtractedData()
+    {
+        return $this->extractedData;
+    }
+
+    /**
+     * @param array $extractedData
+     *
+     * @return void
+     */
+    public function setExtractedData(array $extractedData)
+    {
+        $this->extractedData = $extractedData;
+    }
+
+    /**
+     * Merge provided data with the extracted data
+     *
+     * @param array $additionalData
+     *
+     * @return void
+     */
+    public function mergeExtractedData(array $additionalData)
+    {
+        $this->extractedData = array_merge($this->extractedData, $additionalData);
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Aggregate/HydrateEvent.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Aggregate/HydrateEvent.php
new file mode 100644
index 000000000000..11bab0237974
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Aggregate/HydrateEvent.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Hydrator\Aggregate;
+
+
+use Zend\EventManager\Event;
+
+/**
+ * Event triggered when the {@see \Zend\Stdlib\Hydrator\Aggregate\AggregateHydrator} hydrates
+ * data into an object
+ */
+class HydrateEvent extends Event
+{
+    const EVENT_HYDRATE = 'hydrate';
+
+    /**
+     * {@inheritDoc}
+     */
+    protected $name = self::EVENT_HYDRATE;
+
+    /**
+     * @var object
+     */
+    protected $hydratedObject;
+
+    /**
+     * @var array
+     */
+    protected $hydrationData;
+
+    /**
+     * @param object $target
+     * @param object $hydratedObject
+     * @param array  $hydrationData
+     */
+    public function __construct($target, $hydratedObject, array $hydrationData)
+    {
+        $this->target         = $target;
+        $this->hydratedObject = $hydratedObject;
+        $this->hydrationData  = $hydrationData;
+    }
+
+    /**
+     * Retrieves the object that is being hydrated
+     *
+     * @return object
+     */
+    public function getHydratedObject()
+    {
+        return $this->hydratedObject;
+    }
+
+    /**
+     * @param object $hydratedObject
+     */
+    public function setHydratedObject($hydratedObject)
+    {
+        $this->hydratedObject = $hydratedObject;
+    }
+
+    /**
+     * Retrieves the data that is being used for hydration
+     *
+     * @return array
+     */
+    public function getHydrationData()
+    {
+        return $this->hydrationData;
+    }
+
+    /**
+     * @param array $hydrationData
+     */
+    public function setHydrationData(array $hydrationData)
+    {
+        $this->hydrationData = $hydrationData;
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Aggregate/HydratorListener.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Aggregate/HydratorListener.php
new file mode 100644
index 000000000000..68cc67274cb9
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Aggregate/HydratorListener.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Hydrator\Aggregate;
+
+
+use Zend\EventManager\AbstractListenerAggregate;
+use Zend\EventManager\EventManagerInterface;
+use Zend\Stdlib\Hydrator\HydratorInterface;
+
+/**
+ * Aggregate listener wrapping around a hydrator. Listens
+ * to {@see \Zend\Stdlib\Hydrator\Aggregate::EVENT_HYDRATE} and
+ * {@see \Zend\Stdlib\Hydrator\Aggregate::EVENT_EXTRACT}
+ */
+class HydratorListener extends AbstractListenerAggregate
+{
+    /**
+     * @var \Zend\Stdlib\Hydrator\HydratorInterface
+     */
+    protected $hydrator;
+
+    /**
+     * @param \Zend\Stdlib\Hydrator\HydratorInterface $hydrator
+     */
+    public function __construct(HydratorInterface $hydrator)
+    {
+        $this->hydrator = $hydrator;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function attach(EventManagerInterface $events)
+    {
+        $this->listeners[] = $events->attach(HydrateEvent::EVENT_HYDRATE, array($this, 'onHydrate'));
+        $this->listeners[] = $events->attach(ExtractEvent::EVENT_EXTRACT, array($this, 'onExtract'));
+    }
+
+    /**
+     * Callback to be used when {@see \Zend\Stdlib\Hydrator\Aggregate\HydrateEvent::EVENT_HYDRATE} is triggered
+     *
+     * @param \Zend\Stdlib\Hydrator\Aggregate\HydrateEvent $event
+     *
+     * @return object
+     *
+     * @internal
+     */
+    public function onHydrate(HydrateEvent $event)
+    {
+        $object = $this->hydrator->hydrate($event->getHydrationData(), $event->getHydratedObject());
+
+        $event->setHydratedObject($object);
+
+        return $object;
+    }
+
+    /**
+     * Callback to be used when {@see \Zend\Stdlib\Hydrator\Aggregate\ExtractEvent::EVENT_EXTRACT} is triggered
+     *
+     * @param \Zend\Stdlib\Hydrator\Aggregate\ExtractEvent $event
+     *
+     * @return array
+     *
+     * @internal
+     */
+    public function onExtract(ExtractEvent $event)
+    {
+        $data = $this->hydrator->extract($event->getExtractionObject());
+
+        $event->mergeExtractedData($data);
+
+        return $data;
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/ArraySerializable.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/ArraySerializable.php
new file mode 100644
index 000000000000..d9631122e15e
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/ArraySerializable.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Hydrator;
+
+use Zend\Stdlib\Exception;
+
+class ArraySerializable extends AbstractHydrator
+{
+
+    /**
+     * Extract values from the provided object
+     *
+     * Extracts values via the object's getArrayCopy() method.
+     *
+     * @param  object $object
+     * @return array
+     * @throws Exception\BadMethodCallException for an $object not implementing getArrayCopy()
+     */
+    public function extract($object)
+    {
+        if (!is_callable(array($object, 'getArrayCopy'))) {
+            throw new Exception\BadMethodCallException(sprintf(
+                '%s expects the provided object to implement getArrayCopy()', __METHOD__
+            ));
+        }
+
+        $data = $object->getArrayCopy();
+
+        foreach ($data as $name => $value) {
+            if (!$this->getFilter()->filter($name)) {
+                unset($data[$name]);
+                continue;
+            }
+
+            $data[$name] = $this->extractValue($name, $value);
+        }
+
+        return $data;
+    }
+
+    /**
+     * Hydrate an object
+     *
+     * Hydrates an object by passing $data to either its exchangeArray() or
+     * populate() method.
+     *
+     * @param  array $data
+     * @param  object $object
+     * @return object
+     * @throws Exception\BadMethodCallException for an $object not implementing exchangeArray() or populate()
+     */
+    public function hydrate(array $data, $object)
+    {
+        $self = $this;
+        array_walk($data, function (&$value, $name) use ($self) {
+            $value = $self->hydrateValue($name, $value);
+        });
+
+        if (is_callable(array($object, 'exchangeArray'))) {
+            $object->exchangeArray($data);
+        } elseif (is_callable(array($object, 'populate'))) {
+            $object->populate($data);
+        } else {
+            throw new Exception\BadMethodCallException(sprintf(
+                '%s expects the provided object to implement exchangeArray() or populate()', __METHOD__
+            ));
+        }
+        return $object;
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/ClassMethods.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/ClassMethods.php
new file mode 100644
index 000000000000..e0c3f99ed473
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/ClassMethods.php
@@ -0,0 +1,190 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Hydrator;
+
+use ReflectionMethod;
+use Traversable;
+use Zend\Stdlib\Exception;
+use Zend\Stdlib\ArrayUtils;
+use Zend\Stdlib\Hydrator\Filter\FilterComposite;
+use Zend\Stdlib\Hydrator\Filter\FilterProviderInterface;
+use Zend\Stdlib\Hydrator\Filter\GetFilter;
+use Zend\Stdlib\Hydrator\Filter\HasFilter;
+use Zend\Stdlib\Hydrator\Filter\IsFilter;
+use Zend\Stdlib\Hydrator\Filter\MethodMatchFilter;
+use Zend\Stdlib\Hydrator\Filter\NumberOfParameterFilter;
+
+class ClassMethods extends AbstractHydrator implements HydratorOptionsInterface
+{
+    /**
+     * Flag defining whether array keys are underscore-separated (true) or camel case (false)
+     * @var bool
+     */
+    protected $underscoreSeparatedKeys = true;
+
+    /**
+     * Define if extract values will use camel case or name with underscore
+     * @param bool|array $underscoreSeparatedKeys
+     */
+    public function __construct($underscoreSeparatedKeys = true)
+    {
+        parent::__construct();
+        $this->setUnderscoreSeparatedKeys($underscoreSeparatedKeys);
+
+        $this->filterComposite->addFilter("is", new IsFilter());
+        $this->filterComposite->addFilter("has", new HasFilter());
+        $this->filterComposite->addFilter("get", new GetFilter());
+        $this->filterComposite->addFilter("parameter", new NumberOfParameterFilter(), FilterComposite::CONDITION_AND);
+    }
+
+    /**
+     * @param  array|Traversable                 $options
+     * @return ClassMethods
+     * @throws Exception\InvalidArgumentException
+     */
+    public function setOptions($options)
+    {
+        if ($options instanceof Traversable) {
+            $options = ArrayUtils::iteratorToArray($options);
+        } elseif (!is_array($options)) {
+            throw new Exception\InvalidArgumentException(
+                'The options parameter must be an array or a Traversable'
+            );
+        }
+        if (isset($options['underscoreSeparatedKeys'])) {
+            $this->setUnderscoreSeparatedKeys($options['underscoreSeparatedKeys']);
+        }
+
+        return $this;
+    }
+
+    /**
+     * @param  bool      $underscoreSeparatedKeys
+     * @return ClassMethods
+     */
+    public function setUnderscoreSeparatedKeys($underscoreSeparatedKeys)
+    {
+        $this->underscoreSeparatedKeys = $underscoreSeparatedKeys;
+
+        return $this;
+    }
+
+    /**
+     * @return bool
+     */
+    public function getUnderscoreSeparatedKeys()
+    {
+        return $this->underscoreSeparatedKeys;
+    }
+
+    /**
+     * Extract values from an object with class methods
+     *
+     * Extracts the getter/setter of the given $object.
+     *
+     * @param  object                           $object
+     * @return array
+     * @throws Exception\BadMethodCallException for a non-object $object
+     */
+    public function extract($object)
+    {
+        if (!is_object($object)) {
+            throw new Exception\BadMethodCallException(sprintf(
+                '%s expects the provided $object to be a PHP object)', __METHOD__
+            ));
+        }
+
+        $filter = null;
+        if ($object instanceof FilterProviderInterface) {
+            $filter = new FilterComposite(
+                array($object->getFilter()),
+                array(new MethodMatchFilter("getFilter"))
+            );
+        } else {
+            $filter = $this->filterComposite;
+        }
+
+        $transform = function ($letters) {
+            $letter = array_shift($letters);
+
+            return '_' . strtolower($letter);
+        };
+        $attributes = array();
+        $methods = get_class_methods($object);
+
+        foreach ($methods as $method) {
+            if (
+                !$filter->filter(
+                    get_class($object) . '::' . $method
+                )
+            ) {
+                continue;
+            }
+
+            $reflectionMethod = new ReflectionMethod(get_class($object) . '::' . $method);
+            if ($reflectionMethod->getNumberOfParameters() > 0) {
+                continue;
+            }
+
+            $attribute = $method;
+            if (preg_match('/^get/', $method)) {
+                $attribute = substr($method, 3);
+                if (!property_exists($object, $attribute)) {
+                    $attribute = lcfirst($attribute);
+                }
+            }
+
+            if ($this->underscoreSeparatedKeys) {
+                $attribute = preg_replace_callback('/([A-Z])/', $transform, $attribute);
+            }
+            $attributes[$attribute] = $this->extractValue($attribute, $object->$method(), $object);
+        }
+
+        return $attributes;
+    }
+
+    /**
+     * Hydrate an object by populating getter/setter methods
+     *
+     * Hydrates an object by getter/setter methods of the object.
+     *
+     * @param  array                            $data
+     * @param  object                           $object
+     * @return object
+     * @throws Exception\BadMethodCallException for a non-object $object
+     */
+    public function hydrate(array $data, $object)
+    {
+        if (!is_object($object)) {
+            throw new Exception\BadMethodCallException(sprintf(
+                '%s expects the provided $object to be a PHP object)', __METHOD__
+            ));
+        }
+
+        $transform = function ($letters) {
+            $letter = substr(array_shift($letters), 1, 1);
+
+            return ucfirst($letter);
+        };
+
+        foreach ($data as $property => $value) {
+            $method = 'set' . ucfirst($property);
+            if ($this->underscoreSeparatedKeys) {
+                $method = preg_replace_callback('/(_[a-z])/', $transform, $method);
+            }
+            if (is_callable(array($object, $method))) {
+                $value = $this->hydrateValue($property, $value, $data);
+                $object->$method($value);
+            }
+        }
+
+        return $object;
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/FilterComposite.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/FilterComposite.php
new file mode 100644
index 000000000000..f5ce7e9c8d03
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/FilterComposite.php
@@ -0,0 +1,198 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link           http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright      Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license        http://framework.zend.com/license/new-bsd New BSD License
+ */
+namespace Zend\Stdlib\Hydrator\Filter;
+
+use ArrayObject;
+use Zend\Stdlib\Exception\InvalidArgumentException;
+
+class FilterComposite implements FilterInterface
+{
+    /**
+     * @var ArrayObject
+     */
+    protected $orFilter;
+
+    /**
+     * @var ArrayObject
+     */
+    protected $andFilter;
+
+    /**
+     * Constant to add with "or" conditition
+     */
+    const CONDITION_OR = 1;
+
+    /**
+     * Constant to add with "and" conditition
+     */
+    const CONDITION_AND = 2;
+
+    /**
+     * Define default Filter
+     *
+     * @throws InvalidArgumentException
+     */
+    public function __construct($orFilter = array(), $andFilter = array())
+    {
+        array_walk($orFilter,
+            function($value, $key) {
+                if (
+                    !is_callable($value)
+                    && !$value instanceof FilterInterface
+                ) {
+                    throw new InvalidArgumentException(
+                        'The value of ' . $key . ' should be either a callable or ' .
+                        'an instance of Zend\Stdlib\Hydrator\Filter\FilterInterface'
+                    );
+                }
+            }
+        );
+
+        array_walk($andFilter,
+            function($value, $key) {
+                if (
+                    !is_callable($value)
+                    && !$value instanceof FilterInterface
+                ) {
+                    throw new InvalidArgumentException(
+                        'The value of ' . $key . '  should be either a callable or ' .
+                        'an instance of Zend\Stdlib\Hydrator\Filter\FilterInterface'
+                    );
+                }
+            }
+        );
+
+        $this->orFilter = new ArrayObject($orFilter);
+        $this->andFilter = new ArrayObject($andFilter);
+    }
+
+    /**
+     * Add a filter to the composite. Has to be indexed with $name in
+     * order to identify a specific filter.
+     *
+     * This example will exclude all methods from the hydration, that starts with 'getService'
+     * <code>
+     * $composite->addFilter('exclude',
+     *     function($method) {
+     *         if (preg_match('/^getService/', $method) {
+     *             return false;
+     *         }
+     *         return true;
+     *     }, FilterComposite::CONDITION_AND
+     * );
+     * </code>
+     *
+     * @param  string                   $name
+     * @param  callable|FilterInterface $filter
+     * @param  int                      $condition Can be either FilterComposite::CONDITION_OR or FilterComposite::CONDITION_AND
+     * @throws InvalidArgumentException
+     * @return FilterComposite
+     */
+    public function addFilter($name, $filter, $condition = self::CONDITION_OR)
+    {
+        if (!is_callable($filter) && !($filter instanceof FilterInterface)) {
+            throw new InvalidArgumentException(
+                'The value of ' . $name . ' should be either a callable or ' .
+                'an instance of Zend\Stdlib\Hydrator\Filter\FilterInterface'
+            );
+        }
+
+        if ($condition === self::CONDITION_OR) {
+            $this->orFilter[$name] = $filter;
+        } elseif ($condition === self::CONDITION_AND) {
+            $this->andFilter[$name] = $filter;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Remove a filter from the composition
+     *
+     * @param $name string Identifier for the filter
+     * @return FilterComposite
+     */
+    public function removeFilter($name)
+    {
+        if (isset($this->orFilter[$name])) {
+            unset($this->orFilter[$name]);
+        }
+
+        if (isset($this->andFilter[$name])) {
+            unset($this->andFilter[$name]);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Check if $name has a filter registered
+     *
+     * @param $name string Identifier for the filter
+     * @return bool
+     */
+    public function hasFilter($name)
+    {
+        return isset($this->orFilter[$name]) || isset($this->andFilter[$name]);
+    }
+
+    /**
+     * Filter the composite based on the AND and OR condition
+     * Will return true if one from the "or conditions" and all from
+     * the "and condition" returns true. Otherwise false
+     *
+     * @param $property string Parameter will be e.g. Parent\Namespace\Class::method
+     * @return bool
+     */
+    public function filter($property)
+    {
+        $andCount = count($this->andFilter);
+        $orCount = count($this->orFilter);
+        // return true if no filters are registered
+        if ($orCount === 0 && $andCount === 0) {
+            return true;
+        } elseif ($orCount === 0 && $andCount !== 0) {
+            $returnValue = true;
+        } else {
+            $returnValue = false;
+        }
+
+        // Check if 1 from the or filters return true
+        foreach ($this->orFilter as $filter) {
+            if (is_callable($filter)) {
+                if ($filter($property) === true) {
+                    $returnValue = true;
+                    break;
+                }
+                continue;
+            } else {
+                if ($filter->filter($property) === true) {
+                    $returnValue = true;
+                    break;
+                }
+            }
+        }
+
+        // Check if all of the and condition return true
+        foreach ($this->andFilter as $filter) {
+            if (is_callable($filter)) {
+                if ($filter($property) === false) {
+                    return false;
+                }
+                continue;
+            } else {
+                if ($filter->filter($property) === false) {
+                    return false;
+                }
+            }
+        }
+
+        return $returnValue;
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/FilterInterface.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/FilterInterface.php
new file mode 100644
index 000000000000..30bd3575a13d
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/FilterInterface.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link           http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright      Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license        http://framework.zend.com/license/new-bsd New BSD License
+ */
+namespace Zend\Stdlib\Hydrator\Filter;
+
+interface FilterInterface
+{
+    /**
+     * Should return true, if the given filter
+     * does not match
+     *
+     * @param string $property The name of the property
+     * @return bool
+     */
+    public function filter($property);
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/FilterProviderInterface.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/FilterProviderInterface.php
new file mode 100644
index 000000000000..18f3597a65a1
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/FilterProviderInterface.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link           http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright      Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license        http://framework.zend.com/license/new-bsd New BSD License
+ */
+namespace Zend\Stdlib\Hydrator\Filter;
+
+interface FilterProviderInterface
+{
+    /**
+     * Provides a filter for hydration
+     *
+     * @return FilterInterface
+     */
+    public function getFilter();
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/GetFilter.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/GetFilter.php
new file mode 100644
index 000000000000..d112396ec016
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/GetFilter.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link           http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright      Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license        http://framework.zend.com/license/new-bsd New BSD License
+ */
+namespace Zend\Stdlib\Hydrator\Filter;
+
+class GetFilter implements FilterInterface
+{
+    public function filter($property)
+    {
+        $pos = strpos($property, '::');
+        if ($pos !== false) {
+            $pos += 2;
+        } else {
+            $pos = 0;
+        }
+
+        if (substr($property, $pos, 3) === 'get') {
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/HasFilter.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/HasFilter.php
new file mode 100644
index 000000000000..dfc23f97f207
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/HasFilter.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link           http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright      Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license        http://framework.zend.com/license/new-bsd New BSD License
+ */
+namespace Zend\Stdlib\Hydrator\Filter;
+
+class HasFilter implements FilterInterface
+{
+    public function filter($property)
+    {
+        $pos = strpos($property, '::');
+        if ($pos !== false) {
+            $pos += 2;
+        } else {
+            $pos = 0;
+        }
+
+        if (substr($property, $pos, 3) === 'has') {
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/IsFilter.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/IsFilter.php
new file mode 100644
index 000000000000..233ae139f6f0
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/IsFilter.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link           http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright      Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license        http://framework.zend.com/license/new-bsd New BSD License
+ */
+namespace Zend\Stdlib\Hydrator\Filter;
+
+class IsFilter implements FilterInterface
+{
+    public function filter($property)
+    {
+        $pos = strpos($property, '::');
+        if ($pos !== false) {
+            $pos += 2;
+        } else {
+            $pos = 0;
+        }
+
+        if (substr($property, $pos, 2) === 'is') {
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/MethodMatchFilter.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/MethodMatchFilter.php
new file mode 100644
index 000000000000..a61cd5a3d614
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/MethodMatchFilter.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link           http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright      Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license        http://framework.zend.com/license/new-bsd New BSD License
+ */
+namespace Zend\Stdlib\Hydrator\Filter;
+
+class MethodMatchFilter implements FilterInterface
+{
+    /**
+     * The method to exclude
+     * @var string
+     */
+    protected $method = null;
+
+    /**
+     * Either an exclude or an include
+     * @var bool
+     */
+    protected $exclude = null;
+
+    /**
+     * @param string $method The method to exclude or include
+     * @param bool $exclude If the method should be excluded
+     */
+    public function __construct($method, $exclude = true)
+    {
+        $this->method = $method;
+        $this->exclude = $exclude;
+    }
+
+    public function filter($property)
+    {
+        $pos = strpos($property, '::');
+        if ($pos !== false) {
+            $pos += 2;
+        } else {
+            $pos = 0;
+        }
+        if (substr($property, $pos) === $this->method) {
+            return $this->exclude ? false : true;
+        }
+        return $this->exclude ? true : false;
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/NumberOfParameterFilter.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/NumberOfParameterFilter.php
new file mode 100644
index 000000000000..7f4e05289f3e
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Filter/NumberOfParameterFilter.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link           http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright      Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license        http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Hydrator\Filter;
+
+use ReflectionException;
+use ReflectionMethod;
+use Zend\Stdlib\Exception\InvalidArgumentException;
+use Zend\Stdlib\Hydrator\Filter\FilterInterface;
+
+class NumberOfParameterFilter implements FilterInterface
+{
+    /**
+     * The number of parameters beeing accepted
+     * @var int
+     */
+    protected $numberOfParameters = null;
+
+    /**
+     * @param int $numberOfParameters Number of accepted parameters
+     */
+    public function __construct($numberOfParameters = 0)
+    {
+        $this->numberOfParameters = 0;
+    }
+
+    /**
+     * @param string $property the name of the property
+     * @return bool
+     * @throws InvalidArgumentException
+     */
+    public function filter($property)
+    {
+        try {
+            $reflectionMethod = new ReflectionMethod($property);
+        } catch (ReflectionException $exception) {
+            throw new InvalidArgumentException(
+                "Method $property doesn't exist"
+            );
+        }
+
+        if ($reflectionMethod->getNumberOfParameters() !== $this->numberOfParameters) {
+            return false;
+        }
+
+        return true;
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/HydratorAwareInterface.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/HydratorAwareInterface.php
new file mode 100644
index 000000000000..f2784b3bb284
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/HydratorAwareInterface.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Hydrator;
+
+interface HydratorAwareInterface
+{
+    /**
+     * Set hydrator
+     *
+     * @param  HydratorInterface $hydrator
+     * @return HydratorAwareInterface
+     */
+    public function setHydrator(HydratorInterface $hydrator);
+
+    /**
+     * Retrieve hydrator
+     *
+     * @return HydratorInterface
+     */
+    public function getHydrator();
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/HydratorInterface.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/HydratorInterface.php
new file mode 100644
index 000000000000..c6b3e89e20a4
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/HydratorInterface.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Hydrator;
+
+interface HydratorInterface
+{
+    /**
+     * Extract values from an object
+     *
+     * @param  object $object
+     * @return array
+     */
+    public function extract($object);
+
+    /**
+     * Hydrate $object with the provided $data.
+     *
+     * @param  array $data
+     * @param  object $object
+     * @return object
+     */
+    public function hydrate(array $data, $object);
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/HydratorOptionsInterface.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/HydratorOptionsInterface.php
new file mode 100644
index 000000000000..740cfb435de3
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/HydratorOptionsInterface.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Hydrator;
+
+interface HydratorOptionsInterface
+{
+    /**
+     * @param  array|\Traversable $options
+     * @return HydratorOptionsInterface
+     */
+    public function setOptions($options);
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/HydratorPluginManager.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/HydratorPluginManager.php
new file mode 100644
index 000000000000..0e9892a25299
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/HydratorPluginManager.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Hydrator;
+
+use Zend\ServiceManager\AbstractPluginManager;
+use Zend\Stdlib\Exception;
+
+/**
+ * Plugin manager implementation for hydrators.
+ *
+ * Enforces that adapters retrieved are instances of HydratorInterface
+ */
+class HydratorPluginManager extends AbstractPluginManager
+{
+    /**
+     * Whether or not to share by default
+     *
+     * @var bool
+     */
+    protected $shareByDefault = false;
+
+    /**
+     * Default set of adapters
+     *
+     * @var array
+     */
+    protected $invokableClasses = array(
+        'arrayserializable' => 'Zend\Stdlib\Hydrator\ArraySerializable',
+        'classmethods'      => 'Zend\Stdlib\Hydrator\ClassMethods',
+        'objectproperty'    => 'Zend\Stdlib\Hydrator\ObjectProperty',
+        'reflection'        => 'Zend\Stdlib\Hydrator\Reflection'
+    );
+
+    /**
+     * {@inheritDoc}
+     */
+    public function validatePlugin($plugin)
+    {
+        if ($plugin instanceof HydratorInterface) {
+            // we're okay
+            return;
+        }
+
+        throw new Exception\RuntimeException(sprintf(
+            'Plugin of type %s is invalid; must implement Zend\Stdlib\Hydrator\HydratorInterface',
+            (is_object($plugin) ? get_class($plugin) : gettype($plugin))
+        ));
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/ObjectProperty.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/ObjectProperty.php
new file mode 100644
index 000000000000..c0bf569a2fed
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/ObjectProperty.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Hydrator;
+
+use Zend\Stdlib\Exception;
+
+class ObjectProperty extends AbstractHydrator
+{
+    /**
+     * Extract values from an object
+     *
+     * Extracts the accessible non-static properties of the given $object.
+     *
+     * @param  object $object
+     * @return array
+     * @throws Exception\BadMethodCallException for a non-object $object
+     */
+    public function extract($object)
+    {
+        if (!is_object($object)) {
+            throw new Exception\BadMethodCallException(sprintf(
+                '%s expects the provided $object to be a PHP object)', __METHOD__
+            ));
+        }
+
+        $data = get_object_vars($object);
+
+        $filter = $this->getFilter();
+        foreach ($data as $name => $value) {
+            // Filter keys, removing any we don't want
+            if (!$filter->filter($name)) {
+                unset($data[$name]);
+                continue;
+            }
+            // Extract data
+            $data[$name] = $this->extractValue($name, $value);
+        }
+
+        return $data;
+    }
+
+    /**
+     * Hydrate an object by populating public properties
+     *
+     * Hydrates an object by setting public properties of the object.
+     *
+     * @param  array $data
+     * @param  object $object
+     * @return object
+     * @throws Exception\BadMethodCallException for a non-object $object
+     */
+    public function hydrate(array $data, $object)
+    {
+        if (!is_object($object)) {
+            throw new Exception\BadMethodCallException(sprintf(
+                '%s expects the provided $object to be a PHP object)', __METHOD__
+            ));
+        }
+        foreach ($data as $property => $value) {
+            $object->$property = $this->hydrateValue($property, $value, $data);
+        }
+        return $object;
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Reflection.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Reflection.php
new file mode 100644
index 000000000000..1c093c88b379
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Reflection.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Hydrator;
+
+use ReflectionClass;
+use Zend\Stdlib\Exception;
+
+class Reflection extends AbstractHydrator
+{
+    /**
+     * Simple in-memory array cache of ReflectionProperties used.
+     * @var array
+     */
+    protected static $reflProperties = array();
+
+    /**
+     * Extract values from an object
+     *
+     * @param  object $object
+     * @return array
+     */
+    public function extract($object)
+    {
+        $result = array();
+        foreach (self::getReflProperties($object) as $property) {
+            $propertyName = $property->getName();
+            if (!$this->filterComposite->filter($propertyName)) {
+                continue;
+            }
+
+            $value = $property->getValue($object);
+            $result[$propertyName] = $this->extractValue($propertyName, $value, $object);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Hydrate $object with the provided $data.
+     *
+     * @param  array $data
+     * @param  object $object
+     * @return object
+     */
+    public function hydrate(array $data, $object)
+    {
+        $reflProperties = self::getReflProperties($object);
+        foreach ($data as $key => $value) {
+            if (isset($reflProperties[$key])) {
+                $reflProperties[$key]->setValue($object, $this->hydrateValue($key, $value, $data));
+            }
+        }
+        return $object;
+    }
+
+    /**
+     * Get a reflection properties from in-memory cache and lazy-load if
+     * class has not been loaded.
+     *
+     * @static
+     * @param string|object $input
+     * @throws Exception\InvalidArgumentException
+     * @return array
+     */
+    protected static function getReflProperties($input)
+    {
+        if (is_object($input)) {
+            $input = get_class($input);
+        } elseif (!is_string($input)) {
+            throw new Exception\InvalidArgumentException('Input must be a string or an object.');
+        }
+
+        if (!isset(static::$reflProperties[$input])) {
+            $reflClass      = new ReflectionClass($input);
+            $reflProperties = $reflClass->getProperties();
+
+            foreach ($reflProperties as $property) {
+                $property->setAccessible(true);
+                static::$reflProperties[$input][$property->getName()] = $property;
+            }
+        }
+
+        return static::$reflProperties[$input];
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Strategy/ClosureStrategy.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Strategy/ClosureStrategy.php
new file mode 100644
index 000000000000..1367b5c06d11
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Strategy/ClosureStrategy.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Hydrator\Strategy;
+
+class ClosureStrategy implements StrategyInterface
+{
+    /**
+     * Function, used in extract method, default:
+     * function($value) {
+     *     return $value;
+     * };
+     * @var callable
+     */
+    protected $extractFunc = null;
+
+    /**
+     * Function, used in hydrate method, default:
+     * function($value) {
+     *     return $value;
+     * };
+     * @var callable
+     */
+    protected $hydrateFunc = null;
+
+    /**
+     * You can describe how your values will extract and hydrate, like this:
+     * $hydrator->addStrategy('category', new ClosureStrategy(
+     *     function(Category $value) {
+     *         return (int)$value->id;
+     *     },
+     *     function($value) {
+     *         return new Category((int)$value);
+     *     }
+     * ));
+     *
+     * @param callable $extractFunc - anonymous function, that extract values
+     * from object
+     * @param callable $hydrateFunc - anonymous function, that hydrate values
+     * into object
+     */
+    public function __construct($extractFunc = null, $hydrateFunc = null)
+    {
+        if (isset($extractFunc)) {
+            if (!is_callable($extractFunc)) {
+                throw new \Exception('$extractFunc must be callable');
+            }
+
+            $this->extractFunc = $extractFunc;
+        } else {
+            $this->extractFunc = function($value) {
+                return $value;
+            };
+        }
+
+        if (isset($hydrateFunc)) {
+            if (!is_callable($hydrateFunc)) {
+                throw new \Exception('$hydrateFunc must be callable');
+            }
+
+            $this->hydrateFunc = $hydrateFunc;
+        } else {
+            $this->hydrateFunc = function($value) {
+                return $value;
+            };
+        }
+    }
+
+    /**
+     * Converts the given value so that it can be extracted by the hydrator.
+     *
+     * @param mixed $value The original value.
+     * @return mixed Returns the value that should be extracted.
+     */
+    public function extract($value)
+    {
+        $func = $this->extractFunc;
+
+        return $func($value);
+    }
+
+    /**
+     * Converts the given value so that it can be hydrated by the hydrator.
+     *
+     * @param mixed $value The original value.
+     * @return mixed Returns the value that should be hydrated.
+     */
+    public function hydrate($value)
+    {
+        $func = $this->hydrateFunc;
+
+        return $func($value);
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Strategy/DefaultStrategy.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Strategy/DefaultStrategy.php
new file mode 100644
index 000000000000..d98f1f4c7277
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Strategy/DefaultStrategy.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Hydrator\Strategy;
+
+class DefaultStrategy implements StrategyInterface
+{
+    /**
+     * Converts the given value so that it can be extracted by the hydrator.
+     *
+     * @param mixed $value The original value.
+     * @return mixed Returns the value that should be extracted.
+     */
+    public function extract($value)
+    {
+        return $value;
+    }
+
+    /**
+     * Converts the given value so that it can be hydrated by the hydrator.
+     *
+     * @param mixed $value The original value.
+     * @return mixed Returns the value that should be hydrated.
+     */
+    public function hydrate($value)
+    {
+        return $value;
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Strategy/SerializableStrategy.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Strategy/SerializableStrategy.php
new file mode 100644
index 000000000000..67b323ad6a01
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Strategy/SerializableStrategy.php
@@ -0,0 +1,123 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Hydrator\Strategy;
+
+use Zend\Stdlib\Exception\InvalidArgumentException;
+use Zend\Serializer\Adapter\AdapterInterface as SerializerAdapter;
+use Zend\Serializer\Serializer as SerializerFactory;
+
+class SerializableStrategy implements StrategyInterface
+{
+    /**
+     * @var string|SerializerAdapter
+     */
+    protected $serializer;
+
+    /**
+     * @var array
+     */
+    protected $serializerOptions = array();
+
+    /**
+     *
+     * @param mixed $serializer string or SerializerAdapter
+     * @param mixed $serializerOptions
+     */
+    public function __construct($serializer, $serializerOptions = null)
+    {
+        $this->setSerializer($serializer);
+        if ($serializerOptions) {
+            $this->setSerializerOptions($serializerOptions);
+        }
+    }
+
+    /**
+     * Serialize the given value so that it can be extracted by the hydrator.
+     *
+     * @param mixed $value The original value.
+     * @return mixed Returns the value that should be extracted.
+     */
+    public function extract($value)
+    {
+        $serializer = $this->getSerializer();
+        return $serializer->serialize($value);
+    }
+
+    /**
+     * Unserialize the given value so that it can be hydrated by the hydrator.
+     *
+     * @param mixed $value The original value.
+     * @return mixed Returns the value that should be hydrated.
+     */
+    public function hydrate($value)
+    {
+        $serializer = $this->getSerializer();
+        return $serializer->unserialize($value);
+    }
+
+    /**
+     * Set serializer
+     *
+     * @param  string|SerializerAdapter $serializer
+     * @return SerializableStrategy
+     */
+    public function setSerializer($serializer)
+    {
+        if (!is_string($serializer) && !$serializer instanceof SerializerAdapter) {
+            throw new InvalidArgumentException(sprintf(
+                '%s expects either a string serializer name or Zend\Serializer\Adapter\AdapterInterface instance; '
+                . 'received "%s"',
+                __METHOD__,
+                (is_object($serializer) ? get_class($serializer) : gettype($serializer))
+            ));
+        }
+        $this->serializer = $serializer;
+        return $this;
+    }
+
+    /**
+     * Get serializer
+     *
+     * @return SerializerAdapter
+     */
+    public function getSerializer()
+    {
+        if (is_string($this->serializer)) {
+            $options = $this->getSerializerOptions();
+            $this->setSerializer(SerializerFactory::factory($this->serializer, $options));
+        } elseif (null === $this->serializer) {
+            $this->setSerializer(SerializerFactory::getDefaultAdapter());
+        }
+
+        return $this->serializer;
+    }
+
+    /**
+     * Set configuration options for instantiating a serializer adapter
+     *
+     * @param  mixed $serializerOptions
+     * @return SerializableStrategy
+     */
+    public function setSerializerOptions($serializerOptions)
+    {
+        $this->serializerOptions = $serializerOptions;
+        return $this;
+    }
+
+    /**
+     * Get configuration options for instantiating a serializer adapter
+     *
+     * @return mixed
+     */
+    public function getSerializerOptions()
+    {
+        return $this->serializerOptions;
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Strategy/StrategyInterface.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Strategy/StrategyInterface.php
new file mode 100644
index 000000000000..85c21cc3f8fc
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/Strategy/StrategyInterface.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Hydrator\Strategy;
+
+interface StrategyInterface
+{
+    /**
+     * Converts the given value so that it can be extracted by the hydrator.
+     *
+     * @param mixed $value The original value.
+     * @return mixed Returns the value that should be extracted.
+     */
+    public function extract($value);
+
+    /**
+     * Converts the given value so that it can be hydrated by the hydrator.
+     *
+     * @param mixed $value The original value.
+     * @return mixed Returns the value that should be hydrated.
+     */
+    public function hydrate($value);
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/StrategyEnabledInterface.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/StrategyEnabledInterface.php
new file mode 100644
index 000000000000..41fda04c4ece
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Hydrator/StrategyEnabledInterface.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\Hydrator;
+
+use Zend\Stdlib\Hydrator\Strategy\StrategyInterface;
+
+interface StrategyEnabledInterface
+{
+    /**
+     * Adds the given strategy under the given name.
+     *
+     * @param string $name The name of the strategy to register.
+     * @param StrategyInterface $strategy The strategy to register.
+     * @return StrategyEnabledInterface
+     */
+    public function addStrategy($name, StrategyInterface $strategy);
+
+    /**
+     * Gets the strategy with the given name.
+     *
+     * @param string $name The name of the strategy to get.
+     * @return StrategyInterface
+     */
+    public function getStrategy($name);
+
+    /**
+     * Checks if the strategy with the given name exists.
+     *
+     * @param string $name The name of the strategy to check for.
+     * @return bool
+     */
+    public function hasStrategy($name);
+
+    /**
+     * Removes the strategy with the given name.
+     *
+     * @param string $name The name of the strategy to remove.
+     * @return StrategyEnabledInterface
+     */
+    public function removeStrategy($name);
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/InitializableInterface.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/InitializableInterface.php
new file mode 100644
index 000000000000..39a71ebf236a
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/InitializableInterface.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+/**
+ * Interface to allow objects to have initialization logic
+ */
+interface InitializableInterface
+{
+    /**
+     * Init an object
+     *
+     * @return void
+     */
+    public function init();
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Message.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Message.php
new file mode 100644
index 000000000000..3e3f1f5be511
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Message.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+use Traversable;
+
+class Message implements MessageInterface
+{
+    /**
+     * @var array
+     */
+    protected $metadata = array();
+
+    /**
+     * @var string
+     */
+    protected $content = '';
+
+    /**
+     * Set message metadata
+     *
+     * Non-destructive setting of message metadata; always adds to the metadata, never overwrites
+     * the entire metadata container.
+     *
+     * @param  string|int|array|Traversable $spec
+     * @param  mixed $value
+     * @throws Exception\InvalidArgumentException
+     * @return Message
+     */
+    public function setMetadata($spec, $value = null)
+    {
+        if (is_scalar($spec)) {
+            $this->metadata[$spec] = $value;
+            return $this;
+        }
+        if (!is_array($spec) && !$spec instanceof Traversable) {
+            throw new Exception\InvalidArgumentException(sprintf(
+                'Expected a string, array, or Traversable argument in first position; received "%s"',
+                (is_object($spec) ? get_class($spec) : gettype($spec))
+            ));
+        }
+        foreach ($spec as $key => $value) {
+            $this->metadata[$key] = $value;
+        }
+        return $this;
+    }
+
+    /**
+     * Retrieve all metadata or a single metadatum as specified by key
+     *
+     * @param  null|string|int $key
+     * @param  null|mixed $default
+     * @throws Exception\InvalidArgumentException
+     * @return mixed
+     */
+    public function getMetadata($key = null, $default = null)
+    {
+        if (null === $key) {
+            return $this->metadata;
+        }
+
+        if (!is_scalar($key)) {
+            throw new Exception\InvalidArgumentException('Non-scalar argument provided for key');
+        }
+
+        if (array_key_exists($key, $this->metadata)) {
+            return $this->metadata[$key];
+        }
+
+        return $default;
+    }
+
+    /**
+     * Set message content
+     *
+     * @param  mixed $value
+     * @return Message
+     */
+    public function setContent($value)
+    {
+        $this->content = $value;
+        return $this;
+    }
+
+    /**
+     * Get message content
+     *
+     * @return mixed
+     */
+    public function getContent()
+    {
+        return $this->content;
+    }
+
+    /**
+     * @return string
+     */
+    public function toString()
+    {
+        $request = '';
+        foreach ($this->getMetadata() as $key => $value) {
+            $request .= sprintf(
+                "%s: %s\r\n",
+                (string) $key,
+                (string) $value
+            );
+        }
+        $request .= "\r\n" . $this->getContent();
+        return $request;
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/MessageInterface.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/MessageInterface.php
new file mode 100644
index 000000000000..0abb1ff6b8af
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/MessageInterface.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+interface MessageInterface
+{
+    /**
+     * Set metadata
+     *
+     * @param  string|int|array|\Traversable $spec
+     * @param  mixed $value
+     */
+    public function setMetadata($spec, $value = null);
+
+    /**
+     * Get metadata
+     *
+     * @param  null|string|int $key
+     * @return mixed
+     */
+    public function getMetadata($key = null);
+
+    /**
+     * Set content
+     *
+     * @param  mixed $content
+     * @return mixed
+     */
+    public function setContent($content);
+
+    /**
+     * Get content
+     *
+     * @return mixed
+     */
+    public function getContent();
+
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ParameterObjectInterface.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ParameterObjectInterface.php
new file mode 100644
index 000000000000..416b8c2985f2
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ParameterObjectInterface.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+interface ParameterObjectInterface
+{
+    /**
+     * @param string $key
+     * @param mixed $value
+     * @return void
+     */
+    public function __set($key, $value);
+
+    /**
+     * @param string $key
+     * @return mixed
+     */
+    public function __get($key);
+
+    /**
+     * @param string $key
+     * @return bool
+     */
+    public function __isset($key);
+
+    /**
+     * @param string $key
+     * @return void
+     */
+    public function __unset($key);
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Parameters.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Parameters.php
new file mode 100644
index 000000000000..be72f3fd98d8
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Parameters.php
@@ -0,0 +1,115 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+use ArrayObject as PhpArrayObject;
+
+class Parameters extends PhpArrayObject implements ParametersInterface
+{
+    /**
+     * Constructor
+     *
+     * Enforces that we have an array, and enforces parameter access to array
+     * elements.
+     *
+     * @param  array $values
+     */
+    public function __construct(array $values = null)
+    {
+        if (null === $values) {
+            $values = array();
+        }
+        parent::__construct($values, ArrayObject::ARRAY_AS_PROPS);
+    }
+
+    /**
+     * Populate from native PHP array
+     *
+     * @param  array $values
+     * @return void
+     */
+    public function fromArray(array $values)
+    {
+        $this->exchangeArray($values);
+    }
+
+    /**
+     * Populate from query string
+     *
+     * @param  string $string
+     * @return void
+     */
+    public function fromString($string)
+    {
+        $array = array();
+        parse_str($string, $array);
+        $this->fromArray($array);
+    }
+
+    /**
+     * Serialize to native PHP array
+     *
+     * @return array
+     */
+    public function toArray()
+    {
+        return $this->getArrayCopy();
+    }
+
+    /**
+     * Serialize to query string
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return http_build_query($this);
+    }
+
+    /**
+     * Retrieve by key
+     *
+     * Returns null if the key does not exist.
+     *
+     * @param  string $name
+     * @return mixed
+     */
+    public function offsetGet($name)
+    {
+        if (isset($this[$name])) {
+            return parent::offsetGet($name);
+        }
+        return null;
+    }
+
+    /**
+     * @param string $name
+     * @param mixed $default optional default value
+     * @return mixed
+     */
+    public function get($name, $default = null)
+    {
+        if (isset($this[$name])) {
+            return parent::offsetGet($name);
+        }
+        return $default;
+    }
+
+    /**
+     * @param string $name
+     * @param mixed $value
+     * @return Parameters
+     */
+    public function set($name, $value)
+    {
+        $this[$name] = $value;
+        return $this;
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ParametersInterface.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ParametersInterface.php
new file mode 100644
index 000000000000..e955b2ac7ac2
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ParametersInterface.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+use ArrayAccess;
+use Countable;
+use Serializable;
+use Traversable;
+
+/*
+ * Basically, an ArrayObject. You could simply define something like:
+ *     class QueryParams extends ArrayObject implements Parameters {}
+ * and have 90% of the functionality
+ */
+interface ParametersInterface extends ArrayAccess, Countable, Serializable, Traversable
+{
+    /**
+     * Constructor
+     *
+     * @param array $values
+     */
+    public function __construct(array $values = null);
+
+    /**
+     * From array
+     *
+     * Allow deserialization from standard array
+     *
+     * @param array $values
+     * @return mixed
+     */
+    public function fromArray(array $values);
+
+    /**
+     * From string
+     *
+     * Allow deserialization from raw body; e.g., for PUT requests
+     *
+     * @param $string
+     * @return mixed
+     */
+    public function fromString($string);
+
+    /**
+     * To array
+     *
+     * Allow serialization back to standard array
+     *
+     * @return mixed
+     */
+    public function toArray();
+
+    /**
+     * To string
+     *
+     * Allow serialization to query format; e.g., for PUT or POST requests
+     *
+     * @return mixed
+     */
+    public function toString();
+
+    /**
+     * Get
+     *
+     * @param string $name
+     * @param mixed|null $default
+     * @return mixed
+     */
+    public function get($name, $default = null);
+
+    /**
+     * Set
+     *
+     * @param string $name
+     * @param mixed $value
+     * @return ParametersInterface
+     */
+    public function set($name, $value);
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/PriorityQueue.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/PriorityQueue.php
new file mode 100644
index 000000000000..bf6a624ac832
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/PriorityQueue.php
@@ -0,0 +1,302 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+use Countable;
+use IteratorAggregate;
+use Serializable;
+
+/**
+ * Re-usable, serializable priority queue implementation
+ *
+ * SplPriorityQueue acts as a heap; on iteration, each item is removed from the
+ * queue. If you wish to re-use such a queue, you need to clone it first. This
+ * makes for some interesting issues if you wish to delete items from the queue,
+ * or, as already stated, iterate over it multiple times.
+ *
+ * This class aggregates items for the queue itself, but also composes an
+ * "inner" iterator in the form of an SplPriorityQueue object for performing
+ * the actual iteration.
+ */
+class PriorityQueue implements Countable, IteratorAggregate, Serializable
+{
+    const EXTR_DATA     = 0x00000001;
+    const EXTR_PRIORITY = 0x00000002;
+    const EXTR_BOTH     = 0x00000003;
+
+    /**
+     * Inner queue class to use for iteration
+     * @var string
+     */
+    protected $queueClass = 'Zend\Stdlib\SplPriorityQueue';
+
+    /**
+     * Actual items aggregated in the priority queue. Each item is an array
+     * with keys "data" and "priority".
+     * @var array
+     */
+    protected $items      = array();
+
+    /**
+     * Inner queue object
+     * @var SplPriorityQueue
+     */
+    protected $queue;
+
+    /**
+     * Insert an item into the queue
+     *
+     * Priority defaults to 1 (low priority) if none provided.
+     *
+     * @param  mixed $data
+     * @param  int $priority
+     * @return PriorityQueue
+     */
+    public function insert($data, $priority = 1)
+    {
+        $priority = (int) $priority;
+        $this->items[] = array(
+            'data'     => $data,
+            'priority' => $priority,
+        );
+        $this->getQueue()->insert($data, $priority);
+        return $this;
+    }
+
+    /**
+     * Remove an item from the queue
+     *
+     * This is different than {@link extract()}; its purpose is to dequeue an
+     * item.
+     *
+     * This operation is potentially expensive, as it requires
+     * re-initialization and re-population of the inner queue.
+     *
+     * Note: this removes the first item matching the provided item found. If
+     * the same item has been added multiple times, it will not remove other
+     * instances.
+     *
+     * @param  mixed $datum
+     * @return bool False if the item was not found, true otherwise.
+     */
+    public function remove($datum)
+    {
+        $found = false;
+        foreach ($this->items as $key => $item) {
+            if ($item['data'] === $datum) {
+                $found = true;
+                break;
+            }
+        }
+        if ($found) {
+            unset($this->items[$key]);
+            $this->queue = null;
+
+            if (!$this->isEmpty()) {
+                $queue = $this->getQueue();
+                foreach ($this->items as $item) {
+                    $queue->insert($item['data'], $item['priority']);
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Is the queue empty?
+     *
+     * @return bool
+     */
+    public function isEmpty()
+    {
+        return (0 === $this->count());
+    }
+
+    /**
+     * How many items are in the queue?
+     *
+     * @return int
+     */
+    public function count()
+    {
+        return count($this->items);
+    }
+
+    /**
+     * Peek at the top node in the queue, based on priority.
+     *
+     * @return mixed
+     */
+    public function top()
+    {
+        return $this->getIterator()->top();
+    }
+
+    /**
+     * Extract a node from the inner queue and sift up
+     *
+     * @return mixed
+     */
+    public function extract()
+    {
+        return $this->getQueue()->extract();
+    }
+
+    /**
+     * Retrieve the inner iterator
+     *
+     * SplPriorityQueue acts as a heap, which typically implies that as items
+     * are iterated, they are also removed. This does not work for situations
+     * where the queue may be iterated multiple times. As such, this class
+     * aggregates the values, and also injects an SplPriorityQueue. This method
+     * retrieves the inner queue object, and clones it for purposes of
+     * iteration.
+     *
+     * @return SplPriorityQueue
+     */
+    public function getIterator()
+    {
+        $queue = $this->getQueue();
+        return clone $queue;
+    }
+
+    /**
+     * Serialize the data structure
+     *
+     * @return string
+     */
+    public function serialize()
+    {
+        return serialize($this->items);
+    }
+
+    /**
+     * Unserialize a string into a PriorityQueue object
+     *
+     * Serialization format is compatible with {@link Zend\Stdlib\SplPriorityQueue}
+     *
+     * @param  string $data
+     * @return void
+     */
+    public function unserialize($data)
+    {
+        foreach (unserialize($data) as $item) {
+            $this->insert($item['data'], $item['priority']);
+        }
+    }
+
+    /**
+     * Serialize to an array
+     *
+     * By default, returns only the item data, and in the order registered (not
+     * sorted). You may provide one of the EXTR_* flags as an argument, allowing
+     * the ability to return priorities or both data and priority.
+     *
+     * @param  int $flag
+     * @return array
+     */
+    public function toArray($flag = self::EXTR_DATA)
+    {
+        switch ($flag) {
+            case self::EXTR_BOTH:
+                return $this->items;
+                break;
+            case self::EXTR_PRIORITY:
+                return array_map(function ($item) {
+                    return $item['priority'];
+                }, $this->items);
+            case self::EXTR_DATA:
+            default:
+                return array_map(function ($item) {
+                    return $item['data'];
+                }, $this->items);
+        }
+    }
+
+    /**
+     * Specify the internal queue class
+     *
+     * Please see {@link getIterator()} for details on the necessity of an
+     * internal queue class. The class provided should extend SplPriorityQueue.
+     *
+     * @param  string $class
+     * @return PriorityQueue
+     */
+    public function setInternalQueueClass($class)
+    {
+        $this->queueClass = (string) $class;
+        return $this;
+    }
+
+    /**
+     * Does the queue contain the given datum?
+     *
+     * @param  mixed $datum
+     * @return bool
+     */
+    public function contains($datum)
+    {
+        foreach ($this->items as $item) {
+            if ($item['data'] === $datum) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Does the queue have an item with the given priority?
+     *
+     * @param  int $priority
+     * @return bool
+     */
+    public function hasPriority($priority)
+    {
+        foreach ($this->items as $item) {
+            if ($item['priority'] === $priority) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Get the inner priority queue instance
+     *
+     * @throws \DomainException
+     * @return SplPriorityQueue
+     */
+    protected function getQueue()
+    {
+        if (null === $this->queue) {
+            $this->queue = new $this->queueClass();
+            if (!$this->queue instanceof \SplPriorityQueue) {
+                throw new \DomainException(sprintf(
+                    'PriorityQueue expects an internal queue of type SplPriorityQueue; received "%s"',
+                    get_class($this->queue)
+                ));
+            }
+        }
+        return $this->queue;
+    }
+
+    /**
+     * Add support for deep cloning
+     *
+     * @return void
+     */
+    public function __clone()
+    {
+        if (null !== $this->queue) {
+            $this->queue = clone $this->queue;
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/README.md b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/README.md
new file mode 100644
index 000000000000..a2dcb84191c2
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/README.md
@@ -0,0 +1,15 @@
+Stdlib Component from ZF2
+=========================
+
+This is the Stdlib component for ZF2.
+
+- File issues at https://github.com/zendframework/zf2/issues
+- Create pull requests against https://github.com/zendframework/zf2
+- Documentation is at http://framework.zend.com/docs
+
+LICENSE
+-------
+
+The files in this archive are released under the [Zend Framework
+license](http://framework.zend.com/license), which is a 3-clause BSD license.
+
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Request.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Request.php
new file mode 100644
index 000000000000..8427bc08f3ab
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Request.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+class Request extends Message implements RequestInterface
+{
+    // generic request implementation
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/RequestInterface.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/RequestInterface.php
new file mode 100644
index 000000000000..4a2252de4e02
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/RequestInterface.php
@@ -0,0 +1,14 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+interface RequestInterface extends MessageInterface
+{
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Response.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Response.php
new file mode 100644
index 000000000000..1c2ea76b19af
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/Response.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+class Response extends Message implements ResponseInterface
+{
+    // generic response implementation
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ResponseInterface.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ResponseInterface.php
new file mode 100644
index 000000000000..cf5d0edd4ee0
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/ResponseInterface.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+interface ResponseInterface extends MessageInterface
+{
+
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/SplPriorityQueue.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/SplPriorityQueue.php
new file mode 100644
index 000000000000..5baa967ff93f
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/SplPriorityQueue.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+use Serializable;
+
+/**
+ * Serializable version of SplPriorityQueue
+ *
+ * Also, provides predictable heap order for datums added with the same priority
+ * (i.e., they will be emitted in the same order they are enqueued).
+ */
+class SplPriorityQueue extends \SplPriorityQueue implements Serializable
+{
+    /**
+     * @var int Seed used to ensure queue order for items of the same priority
+     */
+    protected $serial = PHP_INT_MAX;
+
+    /**
+     * Insert a value with a given priority
+     *
+     * Utilizes {@var $serial} to ensure that values of equal priority are
+     * emitted in the same order in which they are inserted.
+     *
+     * @param  mixed $datum
+     * @param  mixed $priority
+     * @return void
+     */
+    public function insert($datum, $priority)
+    {
+        if (!is_array($priority)) {
+            $priority = array($priority, $this->serial--);
+        }
+        parent::insert($datum, $priority);
+    }
+
+
+    /**
+     * Serialize to an array
+     *
+     * Array will be priority => data pairs
+     *
+     * @return array
+     */
+    public function toArray()
+    {
+        $array = array();
+        foreach (clone $this as $item) {
+            $array[] = $item;
+        }
+        return $array;
+    }
+
+
+    /**
+     * Serialize
+     *
+     * @return string
+     */
+    public function serialize()
+    {
+        $clone = clone $this;
+        $clone->setExtractFlags(self::EXTR_BOTH);
+
+        $data = array();
+        foreach ($clone as $item) {
+            $data[] = $item;
+        }
+
+        return serialize($data);
+    }
+
+    /**
+     * Deserialize
+     *
+     * @param  string $data
+     * @return void
+     */
+    public function unserialize($data)
+    {
+        foreach (unserialize($data) as $item) {
+            $this->insert($item['data'], $item['priority']);
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/SplQueue.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/SplQueue.php
new file mode 100644
index 000000000000..e18ebc682184
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/SplQueue.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+use Serializable;
+
+/**
+ * Serializable version of SplQueue
+ */
+class SplQueue extends \SplQueue implements Serializable
+{
+    /**
+     * Return an array representing the queue
+     *
+     * @return array
+     */
+    public function toArray()
+    {
+        $array = array();
+        foreach ($this as $item) {
+            $array[] = $item;
+        }
+        return $array;
+    }
+
+    /**
+     * Serialize
+     *
+     * @return string
+     */
+    public function serialize()
+    {
+        return serialize($this->toArray());
+    }
+
+    /**
+     * Unserialize
+     *
+     * @param  string $data
+     * @return void
+     */
+    public function unserialize($data)
+    {
+        foreach (unserialize($data) as $item) {
+            $this->push($item);
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/SplStack.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/SplStack.php
new file mode 100644
index 000000000000..3bb8f679601b
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/SplStack.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+use Serializable;
+
+/**
+ * Serializable version of SplStack
+ */
+class SplStack extends \SplStack implements Serializable
+{
+    /**
+     * Serialize to an array representing the stack
+     *
+     * @return array
+     */
+    public function toArray()
+    {
+        $array = array();
+        foreach ($this as $item) {
+            $array[] = $item;
+        }
+        return $array;
+    }
+
+    /**
+     * Serialize
+     *
+     * @return string
+     */
+    public function serialize()
+    {
+        return serialize($this->toArray());
+    }
+
+    /**
+     * Unserialize
+     *
+     * @param  string $data
+     * @return void
+     */
+    public function unserialize($data)
+    {
+        foreach (unserialize($data) as $item) {
+            $this->unshift($item);
+        }
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringUtils.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringUtils.php
new file mode 100644
index 000000000000..2945f9aa6275
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringUtils.php
@@ -0,0 +1,189 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib;
+
+use Zend\Stdlib\ErrorHandler;
+use Zend\Stdlib\StringWrapper\StringWrapperInterface;
+
+/**
+ * Utility class for handling strings of different character encodings
+ * using available PHP extensions.
+ *
+ * Declared abstract, as we have no need for instantiation.
+ */
+abstract class StringUtils
+{
+
+    /**
+     * Ordered list of registered string wrapper instances
+     *
+     * @var StringWrapperInterface[]
+     */
+    protected static $wrapperRegistry = null;
+
+    /**
+     * A list of known single-byte character encodings (upper-case)
+     *
+     * @var string[]
+     */
+    protected static $singleByteEncodings = array(
+        'ASCII', '7BIT', '8BIT',
+        'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4', 'ISO-8859-5',
+        'ISO-8859-6', 'ISO-8859-7', 'ISO-8859-8', 'ISO-8859-9', 'ISO-8859-10',
+        'ISO-8859-11', 'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15', 'ISO-8859-16',
+        'CP-1251', 'CP-1252',
+        // TODO
+    );
+
+    /**
+     * Is PCRE compiled with Unicode support?
+     *
+     * @var bool
+     **/
+    protected static $hasPcreUnicodeSupport = null;
+
+    /**
+     * Get registered wrapper classes
+     *
+     * @return string[]
+     */
+    public static function getRegisteredWrappers()
+    {
+        if (static::$wrapperRegistry === null) {
+            static::$wrapperRegistry = array();
+
+            if (extension_loaded('intl')) {
+                static::$wrapperRegistry[] = 'Zend\Stdlib\StringWrapper\Intl';
+            }
+
+            if (extension_loaded('mbstring')) {
+                static::$wrapperRegistry[] = 'Zend\Stdlib\StringWrapper\MbString';
+            }
+
+            if (extension_loaded('iconv')) {
+                static::$wrapperRegistry[] = 'Zend\Stdlib\StringWrapper\Iconv';
+            }
+
+            static::$wrapperRegistry[] = 'Zend\Stdlib\StringWrapper\Native';
+        }
+
+        return static::$wrapperRegistry;
+    }
+
+    /**
+     * Register a string wrapper class
+     *
+     * @param string $wrapper
+     * @return void
+     */
+    public static function registerWrapper($wrapper)
+    {
+        $wrapper = (string) $wrapper;
+        if (!in_array($wrapper, static::$wrapperRegistry, true)) {
+            static::$wrapperRegistry[] = $wrapper;
+        }
+    }
+
+    /**
+     * Unregister a string wrapper class
+     *
+     * @param string $wrapper
+     * @return void
+     */
+    public static function unregisterWrapper($wrapper)
+    {
+        $index = array_search((string) $wrapper, static::$wrapperRegistry, true);
+        if ($index !== false) {
+            unset(static::$wrapperRegistry[$index]);
+        }
+    }
+
+    /**
+     * Reset all registered wrappers so the default wrappers will be used
+     *
+     * @return void
+     */
+    public static function resetRegisteredWrappers()
+    {
+        static::$wrapperRegistry = null;
+    }
+
+    /**
+     * Get the first string wrapper supporting the given character encoding
+     * and supports to convert into the given convert encoding.
+     *
+     * @param string      $encoding        Character encoding to support
+     * @param string|null $convertEncoding OPTIONAL character encoding to convert in
+     * @return StringWrapperInterface
+     * @throws Exception\RuntimeException If no wrapper supports given character encodings
+     */
+    public static function getWrapper($encoding = 'UTF-8', $convertEncoding = null)
+    {
+        foreach (static::getRegisteredWrappers() as $wrapperClass) {
+            if ($wrapperClass::isSupported($encoding, $convertEncoding)) {
+                $wrapper = new $wrapperClass($encoding, $convertEncoding);
+                $wrapper->setEncoding($encoding, $convertEncoding);
+                return $wrapper;
+            }
+        }
+
+        throw new Exception\RuntimeException(
+            'No wrapper found supporting "' . $encoding . '"'
+            . (($convertEncoding !== null) ? ' and "' . $convertEncoding . '"' : '')
+        );
+    }
+
+    /**
+     * Get a list of all known single-byte character encodings
+     *
+     * @return string[]
+     */
+    public static function getSingleByteEncodings()
+    {
+        return static::$singleByteEncodings;
+    }
+
+    /**
+     * Check if a given encoding is a known single-byte character encoding
+     *
+     * @param string $encoding
+     * @return bool
+     */
+    public static function isSingleByteEncoding($encoding)
+    {
+        return in_array(strtoupper($encoding), static::$singleByteEncodings);
+    }
+
+    /**
+     * Check if a given string is valid UTF-8 encoded
+     *
+     * @param string $str
+     * @return bool
+     */
+    public static function isValidUtf8($str)
+    {
+        return is_string($str) && ($str === '' || preg_match('/^./su', $str) == 1);
+    }
+
+    /**
+     * Is PCRE compiled with Unicode support?
+     *
+     * @return bool
+     */
+    public static function hasPcreUnicodeSupport()
+    {
+        if (static::$hasPcreUnicodeSupport === null) {
+            ErrorHandler::start();
+            static::$hasPcreUnicodeSupport = defined('PREG_BAD_UTF8_OFFSET_ERROR') && preg_match('/\pL/u', 'a') == 1;
+            ErrorHandler::stop();
+        }
+        return static::$hasPcreUnicodeSupport;
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringWrapper/AbstractStringWrapper.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringWrapper/AbstractStringWrapper.php
new file mode 100644
index 000000000000..e22649e7fa22
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringWrapper/AbstractStringWrapper.php
@@ -0,0 +1,272 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\StringWrapper;
+
+use Zend\Stdlib\Exception;
+use Zend\Stdlib\StringUtils;
+
+abstract class AbstractStringWrapper implements StringWrapperInterface
+{
+    /**
+     * The character encoding working on
+     * @var string|null
+     */
+    protected $encoding = 'UTF-8';
+
+    /**
+     * An optionally character encoding to convert to
+     * @var string|null
+     */
+    protected $convertEncoding;
+
+    /**
+     * Check if the given character encoding is supported by this wrapper
+     * and the character encoding to convert to is also supported.
+     *
+     * @param  string      $encoding
+     * @param  string|null $convertEncoding
+     * @return bool
+     */
+    public static function isSupported($encoding, $convertEncoding = null)
+    {
+        $supportedEncodings = static::getSupportedEncodings();
+
+        if (!in_array(strtoupper($encoding), $supportedEncodings)) {
+            return false;
+        }
+
+        if ($convertEncoding !== null && !in_array(strtoupper($convertEncoding), $supportedEncodings)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Set character encoding working with and convert to
+     *
+     * @param string      $encoding         The character encoding to work with
+     * @param string|null $convertEncoding  The character encoding to convert to
+     * @return StringWrapperInterface
+     */
+    public function setEncoding($encoding, $convertEncoding = null)
+    {
+        $supportedEncodings = static::getSupportedEncodings();
+
+        $encodingUpper = strtoupper($encoding);
+        if (!in_array($encodingUpper, $supportedEncodings)) {
+            throw new Exception\InvalidArgumentException(
+                'Wrapper doesn\'t support character encoding "' . $encoding . '"'
+            );
+        }
+
+
+        if ($convertEncoding !== null) {
+            $convertEncodingUpper = strtoupper($convertEncoding);
+            if (!in_array($convertEncodingUpper, $supportedEncodings)) {
+                throw new Exception\InvalidArgumentException(
+                    'Wrapper doesn\'t support character encoding "' . $convertEncoding . '"'
+                );
+            }
+
+            $this->convertEncoding = $convertEncodingUpper;
+        } else {
+            $this->convertEncoding = null;
+        }
+        $this->encoding = $encodingUpper;
+
+        return $this;
+    }
+
+    /**
+     * Get the defined character encoding to work with
+     *
+     * @return string
+     * @throws Exception\LogicException If no encoding was defined
+     */
+    public function getEncoding()
+    {
+        return $this->encoding;
+    }
+
+    /**
+     * Get the defined character encoding to convert to
+     *
+     * @return string|null
+    */
+    public function getConvertEncoding()
+    {
+        return $this->convertEncoding;
+    }
+
+    /**
+     * Convert a string from defined character encoding to the defined convert encoding
+     *
+     * @param string  $str
+     * @param bool $reverse
+     * @return string|false
+     */
+    public function convert($str, $reverse = false)
+    {
+        $encoding        = $this->getEncoding();
+        $convertEncoding = $this->getConvertEncoding();
+        if ($convertEncoding === null) {
+            throw new Exception\LogicException(
+                'No convert encoding defined'
+            );
+        }
+
+        if ($encoding === $convertEncoding) {
+            return $str;
+        }
+
+        $from = $reverse ? $convertEncoding : $encoding;
+        $to   = $reverse ? $encoding : $convertEncoding;
+        throw new Exception\RuntimeException(sprintf(
+            'Converting from "%s" to "%s" isn\'t supported by this string wrapper',
+            $from,
+            $to
+        ));
+    }
+
+    /**
+     * Wraps a string to a given number of characters
+     *
+     * @param  string  $string
+     * @param  int $width
+     * @param  string  $break
+     * @param  bool $cut
+     * @return string|false
+     */
+    public function wordWrap($string, $width = 75, $break = "\n", $cut = false)
+    {
+        $string = (string) $string;
+        if ($string === '') {
+            return '';
+        }
+
+        $break = (string) $break;
+        if ($break === '') {
+            throw new Exception\InvalidArgumentException('Break string cannot be empty');
+        }
+
+        $width = (int) $width;
+        if ($width === 0 && $cut) {
+            throw new Exception\InvalidArgumentException('Cannot force cut when width is zero');
+        }
+
+        if (StringUtils::isSingleByteEncoding($this->getEncoding())) {
+            return wordwrap($string, $width, $break, $cut);
+        }
+
+        $stringWidth = $this->strlen($string);
+        $breakWidth  = $this->strlen($break);
+
+        $result    = '';
+        $lastStart = $lastSpace = 0;
+
+        for ($current = 0; $current < $stringWidth; $current++) {
+            $char = $this->substr($string, $current, 1);
+
+            $possibleBreak = $char;
+            if ($breakWidth !== 1) {
+                $possibleBreak = $this->substr($string, $current, $breakWidth);
+            }
+
+            if ($possibleBreak === $break) {
+                $result    .= $this->substr($string, $lastStart, $current - $lastStart + $breakWidth);
+                $current   += $breakWidth - 1;
+                $lastStart  = $lastSpace = $current + 1;
+                continue;
+            }
+
+            if ($char === ' ') {
+                if ($current - $lastStart >= $width) {
+                    $result    .= $this->substr($string, $lastStart, $current - $lastStart) . $break;
+                    $lastStart  = $current + 1;
+                }
+
+                $lastSpace = $current;
+                continue;
+            }
+
+            if ($current - $lastStart >= $width && $cut && $lastStart >= $lastSpace) {
+                $result    .= $this->substr($string, $lastStart, $current - $lastStart) . $break;
+                $lastStart  = $lastSpace = $current;
+                continue;
+            }
+
+            if ($current - $lastStart >= $width && $lastStart < $lastSpace) {
+                $result    .= $this->substr($string, $lastStart, $lastSpace - $lastStart) . $break;
+                $lastStart  = $lastSpace = $lastSpace + 1;
+                continue;
+            }
+        }
+
+        if ($lastStart !== $current) {
+            $result .= $this->substr($string, $lastStart, $current - $lastStart);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Pad a string to a certain length with another string
+     *
+     * @param  string  $input
+     * @param  int $padLength
+     * @param  string  $padString
+     * @param  int $padType
+     * @return string
+     */
+    public function strPad($input, $padLength, $padString = ' ', $padType = STR_PAD_RIGHT)
+    {
+        if (StringUtils::isSingleByteEncoding($this->getEncoding())) {
+            return str_pad($input, $padLength, $padString, $padType);
+        }
+
+        $lengthOfPadding = $padLength - $this->strlen($input);
+        if ($lengthOfPadding <= 0) {
+            return $input;
+        }
+
+        $padStringLength = $this->strlen($padString);
+        if ($padStringLength === 0) {
+            return $input;
+        }
+
+        $repeatCount = floor($lengthOfPadding / $padStringLength);
+
+        if ($padType === STR_PAD_BOTH) {
+            $lastStringLeft  = '';
+            $lastStringRight = '';
+            $repeatCountLeft = $repeatCountRight = ($repeatCount - $repeatCount % 2) / 2;
+
+            $lastStringLength       = $lengthOfPadding - 2 * $repeatCountLeft * $padStringLength;
+            $lastStringLeftLength   = $lastStringRightLength = floor($lastStringLength / 2);
+            $lastStringRightLength += $lastStringLength % 2;
+
+            $lastStringLeft  = $this->substr($padString, 0, $lastStringLeftLength);
+            $lastStringRight = $this->substr($padString, 0, $lastStringRightLength);
+
+            return str_repeat($padString, $repeatCountLeft) . $lastStringLeft
+                . $input
+                . str_repeat($padString, $repeatCountRight) . $lastStringRight;
+        }
+
+        $lastString = $this->substr($padString, 0, $lengthOfPadding % $padStringLength);
+
+        if ($padType === STR_PAD_LEFT) {
+            return str_repeat($padString, $repeatCount) . $lastString . $input;
+        }
+
+        return $input . str_repeat($padString, $repeatCount) . $lastString;
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringWrapper/Iconv.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringWrapper/Iconv.php
new file mode 100644
index 000000000000..35dc39a1c91c
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringWrapper/Iconv.php
@@ -0,0 +1,289 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\StringWrapper;
+
+use Zend\Stdlib\Exception;
+
+class Iconv extends AbstractStringWrapper
+{
+    /**
+     * List of supported character sets (upper case)
+     *
+     * @var string[]
+     * @link http://www.gnu.org/software/libiconv/
+     */
+    protected static $encodings = array(
+        // European languages
+        'ASCII',
+        'ISO-8859-1',
+        'ISO-8859-2',
+        'ISO-8859-3',
+        'ISO-8859-4',
+        'ISO-8859-5',
+        'ISO-8859-7',
+        'ISO-8859-9',
+        'ISO-8859-10',
+        'ISO-8859-13',
+        'ISO-8859-14',
+        'ISO-8859-15',
+        'ISO-8859-16',
+        'KOI8-R',
+        'KOI8-U',
+        'KOI8-RU',
+        'CP1250',
+        'CP1251',
+        'CP1252',
+        'CP1253',
+        'CP1254',
+        'CP1257',
+        'CP850',
+        'CP866',
+        'CP1131',
+        'MACROMAN',
+        'MACCENTRALEUROPE',
+        'MACICELAND',
+        'MACCROATIAN',
+        'MACROMANIA',
+        'MACCYRILLIC',
+        'MACUKRAINE',
+        'MACGREEK',
+        'MACTURKISH',
+        'MACINTOSH',
+
+        // Semitic languages
+        'ISO-8859-6',
+        'ISO-8859-8',
+        'CP1255',
+        'CP1256',
+        'CP862',
+        'MACHEBREW',
+        'MACARABIC',
+
+        // Japanese
+        'EUC-JP',
+        'SHIFT_JIS',
+        'CP932',
+        'ISO-2022-JP',
+        'ISO-2022-JP-2',
+        'ISO-2022-JP-1',
+
+        // Chinese
+        'EUC-CN',
+        'HZ',
+        'GBK',
+        'CP936',
+        'GB18030',
+        'EUC-TW',
+        'BIG5',
+        'CP950',
+        'BIG5-HKSCS',
+        'BIG5-HKSCS:2004',
+        'BIG5-HKSCS:2001',
+        'BIG5-HKSCS:1999',
+        'ISO-2022-CN',
+        'ISO-2022-CN-EXT',
+
+        // Korean
+        'EUC-KR',
+        'CP949',
+        'ISO-2022-KR',
+        'JOHAB',
+
+        // Armenian
+        'ARMSCII-8',
+
+        // Georgian
+        'GEORGIAN-ACADEMY',
+        'GEORGIAN-PS',
+
+        // Tajik
+        'KOI8-T',
+
+        // Kazakh
+        'PT154',
+        'RK1048',
+
+        // Thai
+        'ISO-8859-11',
+        'TIS-620',
+        'CP874',
+        'MACTHAI',
+
+        // Laotian
+        'MULELAO-1',
+        'CP1133',
+
+        // Vietnamese
+        'VISCII',
+        'TCVN',
+        'CP1258',
+
+        // Platform specifics
+        'HP-ROMAN8',
+        'NEXTSTEP',
+
+        // Full Unicode
+        'UTF-8',
+        'UCS-2',
+        'UCS-2BE',
+        'UCS-2LE',
+        'UCS-4',
+        'UCS-4BE',
+        'UCS-4LE',
+        'UTF-16',
+        'UTF-16BE',
+        'UTF-16LE',
+        'UTF-32',
+        'UTF-32BE',
+        'UTF-32LE',
+        'UTF-7',
+        'C99',
+        'JAVA',
+
+        /* Commented out because that's internal encodings not existing in real world
+        // Full Unicode, in terms of uint16_t or uint32_t (with machine dependent endianness and alignment)
+        'UCS-2-INTERNAL',
+        'UCS-4-INTERNAL',
+
+        // Locale dependent, in terms of `char' or `wchar_t' (with machine dependent endianness and alignment,
+        // and with OS and locale dependent semantics)
+        'char',
+        'wchar_t',
+        '', // The empty encoding name is equivalent to "char": it denotes the locale dependent character encoding.
+        */
+
+        // When configured with the option --enable-extra-encodings,
+        // it also provides support for a few extra encodings:
+
+        // European languages
+        'CP437',
+        'CP737',
+        'CP775',
+        'CP852',
+        'CP853',
+        'CP855',
+        'CP857',
+        'CP858',
+        'CP860',
+        'CP861',
+        'CP863',
+        'CP865',
+        'CP869',
+        'CP1125',
+
+        // Semitic languages
+        'CP864',
+
+        // Japanese
+        'EUC-JISX0213',
+        'Shift_JISX0213',
+        'ISO-2022-JP-3',
+
+        // Chinese
+        'BIG5-2003', // (experimental)
+
+        // Turkmen
+        'TDS565',
+
+        // Platform specifics
+        'ATARIST',
+        'RISCOS-LATIN1',
+    );
+
+    /**
+     * Get a list of supported character encodings
+     *
+     * @return string[]
+     */
+    public static function getSupportedEncodings()
+    {
+        return static::$encodings;
+    }
+
+    /**
+     * Constructor
+     *
+     * @throws Exception\ExtensionNotLoadedException
+     */
+    public function __construct()
+    {
+        if (!extension_loaded('iconv')) {
+            throw new Exception\ExtensionNotLoadedException(
+                'PHP extension "iconv" is required for this wrapper'
+            );
+        }
+    }
+
+    /**
+     * Returns the length of the given string
+     *
+     * @param string $str
+     * @return int|false
+     */
+    public function strlen($str)
+    {
+        return iconv_strlen($str, $this->getEncoding());
+    }
+
+    /**
+     * Returns the portion of string specified by the start and length parameters
+     *
+     * @param string   $str
+     * @param int      $offset
+     * @param int|null $length
+     * @return string|false
+     */
+    public function substr($str, $offset = 0, $length = null)
+    {
+        return iconv_substr($str, $offset, $length, $this->getEncoding());
+    }
+
+    /**
+     * Find the position of the first occurrence of a substring in a string
+     *
+     * @param string $haystack
+     * @param string $needle
+     * @param int    $offset
+     * @return int|false
+     */
+    public function strpos($haystack, $needle, $offset = 0)
+    {
+        return iconv_strpos($haystack, $needle, $offset, $this->getEncoding());
+    }
+
+    /**
+     * Convert a string from defined encoding to the defined convert encoding
+     *
+     * @param string  $str
+     * @param bool $reverse
+     * @return string|false
+     */
+    public function convert($str, $reverse = false)
+    {
+        $encoding        = $this->getEncoding();
+        $convertEncoding = $this->getConvertEncoding();
+        if ($convertEncoding === null) {
+            throw new Exception\LogicException(
+                'No convert encoding defined'
+            );
+        }
+
+        if ($encoding === $convertEncoding) {
+            return $str;
+        }
+
+        $fromEncoding = $reverse ? $convertEncoding : $encoding;
+        $toEncoding   = $reverse ? $encoding : $convertEncoding;
+
+        // automatically add "//IGNORE" to not stop converting on invalid characters
+        // invalid characters triggers a notice anyway
+        return iconv($fromEncoding, $toEncoding . '//IGNORE', $str);
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringWrapper/Intl.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringWrapper/Intl.php
new file mode 100644
index 000000000000..1c3973bb9da3
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringWrapper/Intl.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\StringWrapper;
+
+use Zend\Stdlib\Exception;
+
+class Intl extends AbstractStringWrapper
+{
+    /**
+     * List of supported character sets (upper case)
+     *
+     * @var string[]
+     */
+    protected static $encodings = array('UTF-8');
+
+    /**
+     * Get a list of supported character encodings
+     *
+     * @return string[]
+     */
+    public static function getSupportedEncodings()
+    {
+        return static::$encodings;
+    }
+
+    /**
+     * Constructor
+     *
+     * @throws Exception\ExtensionNotLoadedException
+     */
+    public function __construct()
+    {
+        if (!extension_loaded('intl')) {
+            throw new Exception\ExtensionNotLoadedException(
+                'PHP extension "intl" is required for this wrapper'
+            );
+        }
+    }
+
+    /**
+     * Returns the length of the given string
+     *
+     * @param string $str
+     * @return int|false
+     */
+    public function strlen($str)
+    {
+        return grapheme_strlen($str);
+    }
+
+    /**
+     * Returns the portion of string specified by the start and length parameters
+     *
+     * @param string   $str
+     * @param int      $offset
+     * @param int|null $length
+     * @return string|false
+     */
+    public function substr($str, $offset = 0, $length = null)
+    {
+        return grapheme_substr($str, $offset, $length);
+    }
+
+    /**
+     * Find the position of the first occurrence of a substring in a string
+     *
+     * @param string $haystack
+     * @param string $needle
+     * @param int    $offset
+     * @return int|false
+     */
+    public function strpos($haystack, $needle, $offset = 0)
+    {
+        return grapheme_strpos($haystack, $needle, $offset);
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringWrapper/MbString.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringWrapper/MbString.php
new file mode 100644
index 000000000000..cc47d6ee32ea
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringWrapper/MbString.php
@@ -0,0 +1,121 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\StringWrapper;
+
+use Zend\Stdlib\Exception;
+
+class MbString extends AbstractStringWrapper
+{
+    /**
+     * List of supported character sets (upper case)
+     *
+     * @var null|string[]
+     * @link http://php.net/manual/mbstring.supported-encodings.php
+     */
+    protected static $encodings = null;
+
+    /**
+     * Get a list of supported character encodings
+     *
+     * @return string[]
+     */
+    public static function getSupportedEncodings()
+    {
+        if (static::$encodings === null) {
+            static::$encodings = array_map('strtoupper', mb_list_encodings());
+
+            // FIXME: Converting € (UTF-8) to ISO-8859-16 gives a wrong result
+            $indexIso885916 = array_search('ISO-8859-16', static::$encodings, true);
+            if ($indexIso885916 !== false) {
+                unset(static::$encodings[$indexIso885916]);
+            }
+        }
+
+        return static::$encodings;
+    }
+
+    /**
+     * Constructor
+     *
+     * @throws Exception\ExtensionNotLoadedException
+     */
+    public function __construct()
+    {
+        if (!extension_loaded('mbstring')) {
+            throw new Exception\ExtensionNotLoadedException(
+                'PHP extension "mbstring" is required for this wrapper'
+            );
+        }
+    }
+
+    /**
+     * Returns the length of the given string
+     *
+     * @param string $str
+     * @return int|false
+     */
+    public function strlen($str)
+    {
+        return mb_strlen($str, $this->getEncoding());
+    }
+
+    /**
+     * Returns the portion of string specified by the start and length parameters
+     *
+     * @param string   $str
+     * @param int      $offset
+     * @param int|null $length
+     * @return string|false
+     */
+    public function substr($str, $offset = 0, $length = null)
+    {
+        return mb_substr($str, $offset, $length, $this->getEncoding());
+    }
+
+    /**
+     * Find the position of the first occurrence of a substring in a string
+     *
+     * @param string $haystack
+     * @param string $needle
+     * @param int    $offset
+     * @return int|false
+     */
+    public function strpos($haystack, $needle, $offset = 0)
+    {
+        return mb_strpos($haystack, $needle, $offset, $this->getEncoding());
+    }
+
+    /**
+     * Convert a string from defined encoding to the defined convert encoding
+     *
+     * @param string  $str
+     * @param bool $reverse
+     * @return string|false
+     */
+    public function convert($str, $reverse = false)
+    {
+        $encoding        = $this->getEncoding();
+        $convertEncoding = $this->getConvertEncoding();
+
+        if ($convertEncoding === null) {
+            throw new Exception\LogicException(
+                'No convert encoding defined'
+            );
+        }
+
+        if ($encoding === $convertEncoding) {
+            return $str;
+        }
+
+        $fromEncoding = $reverse ? $convertEncoding : $encoding;
+        $toEncoding   = $reverse ? $encoding : $convertEncoding;
+        return mb_convert_encoding($str, $toEncoding, $fromEncoding);
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringWrapper/Native.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringWrapper/Native.php
new file mode 100644
index 000000000000..978b731118d0
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringWrapper/Native.php
@@ -0,0 +1,134 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\StringWrapper;
+
+use Zend\Stdlib\Exception;
+use Zend\Stdlib\StringUtils;
+
+class Native extends AbstractStringWrapper
+{
+    /**
+     * The character encoding working on
+     * (overwritten to change defaut encoding)
+     *
+     * @var string
+     */
+    protected $encoding = 'ASCII';
+
+    /**
+     * Check if the given character encoding is supported by this wrapper
+     * and the character encoding to convert to is also supported.
+     *
+     * @param  string      $encoding
+     * @param  string|null $convertEncoding
+     * @return bool
+     */
+    public static function isSupported($encoding, $convertEncoding = null)
+    {
+        $encodingUpper      = strtoupper($encoding);
+        $supportedEncodings = static::getSupportedEncodings();
+
+        if (!in_array($encodingUpper, $supportedEncodings)) {
+            return false;
+        }
+
+        // This adapter doesn't support to convert between encodings
+        if ($convertEncoding !== null && $encodingUpper !== strtoupper($convertEncoding)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Get a list of supported character encodings
+     *
+     * @return string[]
+     */
+    public static function getSupportedEncodings()
+    {
+        return StringUtils::getSingleByteEncodings();
+    }
+
+    /**
+     * Set character encoding working with and convert to
+     *
+     * @param string      $encoding         The character encoding to work with
+     * @param string|null $convertEncoding  The character encoding to convert to
+     * @return StringWrapperInterface
+     */
+    public function setEncoding($encoding, $convertEncoding = null)
+    {
+        $supportedEncodings = static::getSupportedEncodings();
+
+        $encodingUpper = strtoupper($encoding);
+        if (!in_array($encodingUpper, $supportedEncodings)) {
+            throw new Exception\InvalidArgumentException(
+                'Wrapper doesn\'t support character encoding "' . $encoding . '"'
+            );
+        }
+
+        if ($encodingUpper !== strtoupper($convertEncoding)) {
+            $this->convertEncoding = $encodingUpper;
+        }
+
+        if ($convertEncoding !== null) {
+            if ($encodingUpper !== strtoupper($convertEncoding)) {
+                throw new Exception\InvalidArgumentException(
+                    'Wrapper doesn\'t support to convert between character encodings'
+                );
+            }
+
+            $this->convertEncoding = $encodingUpper;
+        } else {
+            $this->convertEncoding = null;
+        }
+        $this->encoding = $encodingUpper;
+
+        return $this;
+    }
+
+    /**
+     * Returns the length of the given string
+     *
+     * @param string $str
+     * @return int|false
+     */
+    public function strlen($str)
+    {
+        return strlen($str);
+    }
+
+    /**
+     * Returns the portion of string specified by the start and length parameters
+     *
+     * @param string   $str
+     * @param int      $offset
+     * @param int|null $length
+     * @return string|false
+     */
+    public function substr($str, $offset = 0, $length = null)
+    {
+        return substr($str, $offset, $length);
+    }
+
+    /**
+     * Find the position of the first occurrence of a substring in a string
+     *
+     * @param string $haystack
+     * @param string $needle
+     * @param int    $offset
+     * @return int|false
+     */
+    public function strpos($haystack, $needle, $offset = 0)
+    {
+        return strpos($haystack, $needle, $offset);
+    }
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringWrapper/StringWrapperInterface.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringWrapper/StringWrapperInterface.php
new file mode 100644
index 000000000000..974b0be48990
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/StringWrapper/StringWrapperInterface.php
@@ -0,0 +1,111 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+namespace Zend\Stdlib\StringWrapper;
+
+interface StringWrapperInterface
+{
+    /**
+     * Check if the given character encoding is supported by this wrapper
+     * and the character encoding to convert to is also supported.
+     *
+     * @param string      $encoding
+     * @param string|null $convertEncoding
+     */
+    public static function isSupported($encoding, $convertEncoding = null);
+
+    /**
+     * Get a list of supported character encodings
+     *
+     * @return string[]
+     */
+    public static function getSupportedEncodings();
+
+    /**
+     * Set character encoding working with and convert to
+     *
+     * @param string      $encoding         The character encoding to work with
+     * @param string|null $convertEncoding  The character encoding to convert to
+     * @return StringWrapperInterface
+     */
+    public function setEncoding($encoding, $convertEncoding = null);
+
+    /**
+     * Get the defined character encoding to work with (upper case)
+     *
+     * @return string
+     */
+    public function getEncoding();
+
+    /**
+     * Get the defined character encoding to convert to (upper case)
+     *
+     * @return string|null
+     */
+    public function getConvertEncoding();
+
+    /**
+     * Returns the length of the given string
+     *
+     * @param string $str
+     * @return int|false
+     */
+    public function strlen($str);
+
+    /**
+     * Returns the portion of string specified by the start and length parameters
+     *
+     * @param string   $str
+     * @param int      $offset
+     * @param int|null $length
+     * @return string|false
+     */
+    public function substr($str, $offset = 0, $length = null);
+
+    /**
+     * Find the position of the first occurrence of a substring in a string
+     *
+     * @param string $haystack
+     * @param string $needle
+     * @param int    $offset
+     * @return int|false
+     */
+    public function strpos($haystack, $needle, $offset = 0);
+
+    /**
+     * Convert a string from defined encoding to the defined convert encoding
+     *
+     * @param string  $str
+     * @param bool $reverse
+     * @return string|false
+     */
+    public function convert($str, $reverse = false);
+
+    /**
+     * Wraps a string to a given number of characters
+     *
+     * @param  string  $str
+     * @param  int $width
+     * @param  string  $break
+     * @param  bool $cut
+     * @return string
+     */
+    public function wordWrap($str, $width = 75, $break = "\n", $cut = false);
+
+    /**
+     * Pad a string to a certain length with another string
+     *
+     * @param  string  $input
+     * @param  int $padLength
+     * @param  string  $padString
+     * @param  int $padType
+     * @return string
+     */
+    public function strPad($input, $padLength, $padString = ' ', $padType = STR_PAD_RIGHT);
+}
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/compatibility/autoload.php b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/compatibility/autoload.php
new file mode 100644
index 000000000000..cfc5696262e1
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/compatibility/autoload.php
@@ -0,0 +1,14 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
+ * @deprecated
+ */
+
+/**
+ * Legacy purposes only, to prevent code that references it from breaking.
+ */
+trigger_error('Polyfill autoload support (file library/Zend/Stdlib/compatibility/autoload.php) is no longer necessary; please remove your require statement referencing this file', E_USER_DEPRECATED);
diff --git a/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/composer.json b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/composer.json
new file mode 100644
index 000000000000..217c5eaa40ea
--- /dev/null
+++ b/core/vendor/zendframework/zend-stdlib/Zend/Stdlib/composer.json
@@ -0,0 +1,28 @@
+{
+    "name": "zendframework/zend-stdlib",
+    "description": " ",
+    "license": "BSD-3-Clause",
+    "keywords": [
+        "zf2",
+        "stdlib"
+    ],
+    "autoload": {
+        "psr-0": {
+            "Zend\\Stdlib\\": ""
+        }
+    },
+    "target-dir": "Zend/Stdlib",
+    "suggest": {
+        "zendframework/zend-servicemanager": "To support hydrator plugin manager usage",
+        "zendframework/zend-eventmanager":   "To support aggregate hydrator usage"
+    },
+    "require": {
+        "php": ">=5.3.3"
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "2.2-dev",
+            "dev-develop": "2.3-dev"
+        }
+    }
+}
-- 
GitLab