diff --git a/alib2std/src/alib/multimap b/alib2std/src/alib/multimap
new file mode 100644
index 0000000000000000000000000000000000000000..cd9962ffe068006e9f08fa3ddced53d49ac414bf
--- /dev/null
+++ b/alib2std/src/alib/multimap
@@ -0,0 +1 @@
+#include <extensions/container/multimap.hpp>
diff --git a/alib2std/src/extensions/container/multimap.hpp b/alib2std/src/extensions/container/multimap.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d999f538949d76ee9c6f18a3f467a1d21d525d19
--- /dev/null
+++ b/alib2std/src/extensions/container/multimap.hpp
@@ -0,0 +1,395 @@
+/*
+ * multimap.hpp
+ *
+ * This file is part of Algorithms library toolkit.
+ * Copyright (C) 2017 Jan Travnicek (jan.travnicek@fit.cvut.cz)
+
+ * Algorithms library toolkit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * Algorithms library toolkit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with Algorithms library toolkit.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Created on: Apr 1, 2013
+ * Author: Jan Travnicek
+ */
+
+#ifndef __MULTIMAP_HPP_
+#define __MULTIMAP_HPP_
+
+#include <map>
+#include <ostream>
+#include <sstream>
+#include <utility>
+#include <string>
+
+#include "pair.hpp"
+
+#include <extensions/compare.hpp>
+#include <extensions/allocFix.hpp>
+#include <extensions/range.hpp>
+
+namespace ext {
+
+/**
+ * \brief
+ * Class extending the multimap class from the standard library. Original reason is to allow printing of the container with overloaded operator <<.
+ *
+ * The class mimics the behavior of the multimap from the standatd library.
+ *
+ * \tparam T the type of keys inside the multimap
+ * \tparam R the type of values inside the multimap
+ * \tparam Cmp the comparator type used to order keys
+ * \tparam Alloc the allocator of values of type T
+ */
+template < typename T, typename R, typename Cmp = std::less < >, typename Alloc = std::allocator < std::pair < const T, R > > >
+class multimap : public std::multimap < T, R, Cmp, Alloc >, AllocFix < Alloc > {
+public:
+	/**
+	 * Inherit constructors of the standard multimap
+	 */
+	using std::multimap< T, R, Cmp, Alloc >::multimap;
+
+	/**
+	 * Inherit operator = of the standard multimap
+	 */
+	using std::multimap< T, R, Cmp, Alloc >::operator =;
+#ifndef __clang__
+
+	/**
+	 * Default constructor needed by g++ since it is not inherited
+	 */
+	multimap ( ) = default;
+
+	/**
+	 * Copy constructor needed by g++ since it is not inherited
+	 */
+	multimap ( const multimap & other ) = default;
+
+	/**
+	 * Move constructor needed by g++ since it is not inherited
+	 */
+	multimap ( multimap && other ) = default;
+
+	/**
+	 * Copy operator = needed by g++ since it is not inherited
+	 */
+	multimap & operator = ( multimap && other ) = default;
+
+	/**
+	 * Move operator = needed by g++ since it is not inherited
+	 */
+	multimap & operator = ( const multimap & other ) = default;
+#endif
+	/**
+	 * Constructor from range of values.
+	 *
+	 * \tparam Iterator the type of range iterator
+	 *
+	 * \param range the source range
+	 */
+	template < class Iterator >
+	multimap ( const ext::iterator_range < Iterator > & range ) : multimap ( range.begin ( ), range.end ( ) ) {
+	}
+
+	/**
+	 * \brief
+	 * The iterator type is inheried.
+	 */
+	using iterator = typename std::multimap<T, R, Cmp, Alloc>::iterator;
+
+	/**
+	 * \brief
+	 * Inherit all insert methods of the standard multimap.
+	 */
+	using std::multimap< T, R, Cmp, Alloc >::insert;
+
+	/**
+	 * \brief
+	 * Insert variant with explicit key and value parameters.
+	 *
+	 * \param key the key
+	 * \param value the value
+	 *
+	 * \return pair of iterator to inserted key-value pair and true if the value was inserted or false if the key already exited
+	 */
+	iterator insert ( const T & key, const R & value ) {
+		return insert ( std::make_pair ( key, value ) );
+	}
+
+	/**
+	 * \brief
+	 * Insert variant with explicit key and value parameters.
+	 *
+	 * \param key the key
+	 * \param value the value
+	 *
+	 * \return pair of iterator to inserted key-value pair and true if the value was inserted or false if the key already exited
+	 */
+	iterator insert ( const T & key, R && value ) {
+		return insert ( std::make_pair ( key, std::move ( value ) ) );
+	}
+
+	/**
+	 * \brief
+	 * Insert variant with explicit key and value parameters.
+	 *
+	 * \param key the key
+	 * \param value the value
+	 *
+	 * \return pair of iterator to inserted key-value pair and true if the value was inserted or false if the key already exited
+	 */
+	iterator insert ( T && key, const R & value ) {
+		return insert ( std::make_pair ( std::move ( key ), value ) );
+	}
+
+	/**
+	 * \brief
+	 * Insert variant with explicit key and value parameters.
+	 *
+	 * \param key the key
+	 * \param value the value
+	 *
+	 * \return pair of iterator to inserted key-value pair and true if the value was inserted or false if the key already exited
+	 */
+	iterator insert ( T && key, R && value ) {
+		return insert ( std::make_pair ( std::move ( key ), std::move ( value ) ) );
+	}
+
+	/**
+	 * \brief
+	 * Inherited behavior of begin for non-const instance.
+	 *
+	 * \return iterator the first element of multimap
+	 */
+	auto begin ( ) & {
+		return std::multimap < T, R, Cmp, Alloc >::begin ( );
+	}
+
+	/**
+	 * \brief
+	 * Inherited behavior of begin for const instance.
+	 *
+	 * \return const_iterator the first element of multimap
+	 */
+	auto begin ( ) const & {
+		return std::multimap < T, R, Cmp, Alloc >::begin ( );
+	}
+
+	/**
+	 * \brief
+	 * New variant of begin for rvalues.
+	 *
+	 * \return move_iterator the first element of multimap
+	 */
+	auto begin ( ) && {
+		return make_map_move_iterator < T, R > ( this->begin ( ) );
+	}
+
+	/**
+	 * \brief
+	 * Inherited behavior of end for non-const instance.
+	 *
+	 * \return iterator to one after the last element of multimap
+	 */
+	auto end ( ) & {
+		return std::multimap < T, R, Cmp, Alloc >::end ( );
+	}
+
+	/**
+	 * \brief
+	 * Inherited behavior of end for const instance.
+	 *
+	 * \return const_iterator to one after the last element of multimap
+	 */
+	auto end ( ) const & {
+		return std::multimap < T, R, Cmp, Alloc >::end ( );
+	}
+
+	/**
+	 * \brief
+	 * New variant of end for rvalues.
+	 *
+	 * \return move_iterator to one after the last element of multimap
+	 */
+	auto end ( ) && {
+		return make_map_move_iterator < T, R > ( this->end ( ) );
+	}
+
+	/**
+	 * \brief
+	 * Make range of non-const begin to end iterators.
+	 *
+	 * \return full range over container values
+	 */
+	auto range ( ) & {
+		auto endIter = end ( );
+		auto beginIter = begin ( );
+		return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter );
+	}
+
+	/**
+	 * \brief
+	 * Make range of non-const begin to end iterators.
+	 *
+	 * \return full range over container values
+	 */
+	auto range ( ) const & {
+		auto endIter = end ( );
+		auto beginIter = begin ( );
+		return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter );
+	}
+
+	/**
+	 * \brief
+	 * Make range of move begin to end iterators.
+	 *
+	 * \return full range over container values
+	 */
+	auto range ( ) && {
+		auto endIter = std::move ( * this ).end ( );
+		auto beginIter = std::move ( * this ).begin ( );
+		return ext::iterator_range < decltype ( endIter ) > ( beginIter, endIter );
+	}
+
+	/**
+	 * \brief
+	 * Make range of elements with key equal to the @p key.
+	 *
+	 * \tparam K the key used in the query
+	 *
+	 * \param key the value used in the query
+	 *
+	 * \return selected range of elements
+	 */
+	template < class K >
+	auto equal_range ( K && key ) const & {
+		auto range = std::multimap < T, R, Cmp, Alloc >::equal_range ( std::forward < K > ( key ) );
+		return ext::iterator_range < decltype ( range.first ) > ( range.first, range.second );
+	}
+
+	/**
+	 * \brief
+	 * Make range of elements with key equal to the @p key.
+	 *
+	 * \tparam K the key used in the query
+	 *
+	 * \param key the value used in the query
+	 *
+	 * \return selected range of elements
+	 */
+	template < class K >
+	auto equal_range ( K && key ) & {
+		auto range = std::multimap < T, R, Cmp, Alloc >::equal_range ( std::forward < K > ( key ) );
+		return ext::iterator_range < decltype ( range.first ) > ( range.first, range.second );
+	}
+
+	/**
+	 * \brief
+	 * Make range of elements with key equal to the @p key.
+	 *
+	 * \tparam K the key used in the query
+	 *
+	 * \param key the value used in the query
+	 *
+	 * \return selected range of elements
+	 */
+	template < class K >
+	auto equal_range ( K && key ) && {
+		auto range = std::multimap < T, R, Cmp, Alloc >::equal_range ( std::forward < K > ( key ) );
+		return ext::make_iterator_range ( make_map_move_iterator < T, R > ( range.first ), make_map_move_iterator < T, R > ( range.second ) );
+	}
+
+};
+
+/**
+ * \brief
+ * Operator to print the multimap to the output stream.
+ *
+ * \param out the output stream
+ * \param multimap the multimap to print
+ *
+ * \tparam T the type of keys inside the multimap
+ * \tparam R the type of values inside the multimap
+ * \tparam Ts ... remaining unimportant template parameters of the multimap
+ *
+ * \return the output stream from the \p out
+ */
+template< class T, class R, class ... Ts >
+std::ostream& operator<<(std::ostream& out, const ext::multimap<T, R, Ts ... >& multimap) {
+	out << "{";
+
+	bool first = true;
+	for(const std::pair<const T, R>& item : multimap) {
+		if(!first) out << ", ";
+		first = false;
+		out << "(" << item.first << ", " << item.second << ")";
+	}
+
+	out << "}";
+	return out;
+}
+
+/**
+ * \brief
+ * Specialisation of the compare structure implementing the three-way comparison.
+ *
+ * \tparam T the type of keys inside the multimap
+ * \tparam R the type of values inside the multimap
+ * \tparam Ts ... remaining unimportant template parameters of the multimap
+ */
+template < class T, class R, class ... Ts >
+struct compare < ext::multimap < T, R, Ts ... > > {
+
+	/**
+	 * \brief
+	 * Implementation of the three-way comparison.
+	 *
+	 * \param first the left operand of the comparison
+	 * \param second the right operand of the comparison
+	 *
+	 * \return negative value of left < right, positive value if left > right, zero if left == right
+	 */
+	int operator ( ) ( const ext::multimap < T, R, Ts ... > & first, const ext::multimap < T, R, Ts ... > & second) const {
+		if(first.size() < second.size()) return -1;
+		if(first.size() > second.size()) return 1;
+
+		static compare < typename std::decay < T >::type > compT;
+		static compare < typename std::decay < R >::type > compR;
+		for(auto iterF = first.begin(), iterS = second.begin(); iterF != first.end(); ++iterF, ++iterS) {
+			int res = compT(iterF->first, iterS->first);
+			if(res == 0) res = compR(iterF->second, iterS->second);
+			if(res != 0) return res;
+		}
+		return 0;
+	}
+};
+
+/**
+ * \brief
+ * Overload of to_string function.
+ *
+ * \param value the multimap to be converted to string
+ *
+ * \tparam T the type of values inside the multimap
+ * \tparam Ts ... remaining unimportant template parameters of the multimap
+ *
+ * \return string representation
+ */
+template < class T, class R, class ... Ts >
+std::string to_string ( const ext::multimap < T, R, Ts ... > & value ) {
+	std::stringstream ss;
+	ss << value;
+	return ss.str();
+}
+
+} /* namespace ext */
+
+#endif /* __MULTIMAP_HPP_ */
diff --git a/alib2std/test-src/extensions/container/MultimapTest.cpp b/alib2std/test-src/extensions/container/MultimapTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..993567d51db2615542b09026f3b6f2bebc3d2b0b
--- /dev/null
+++ b/alib2std/test-src/extensions/container/MultimapTest.cpp
@@ -0,0 +1,54 @@
+#include <catch2/catch.hpp>
+#include <alib/multimap>
+#include <alib/algorithm>
+
+namespace {
+	class Moveable {
+		int& m_moves;
+		int& m_copies;
+
+		public:
+		Moveable(int& moves, int& copies) : m_moves(moves), m_copies(copies) {
+			m_moves = 0;
+			m_copies = 0;
+		}
+
+		Moveable(const Moveable& src) : m_moves(src.m_moves), m_copies(src.m_copies) {
+			m_copies++;
+		}
+
+		Moveable(Moveable&& src) : m_moves(src.m_moves), m_copies(src.m_copies) {
+			m_moves++;
+		}
+
+		Moveable & operator = ( const Moveable & ) {
+			m_copies ++;
+			return * this;
+		}
+
+		Moveable & operator = ( Moveable && ) {
+			m_moves ++;
+			return * this;
+		}
+
+		bool operator<(const Moveable&) const {
+			return false;
+		}
+	};
+}
+TEST_CASE ( "Multimap", "[unit][std][container]" ) {
+	SECTION ( "Basic" ) {
+		int moves;
+		int copies;
+
+		ext::multimap<Moveable, Moveable> multimap;
+		multimap.insert ( Moveable(moves, copies ), Moveable(moves, copies) );
+		ext::multimap<Moveable, Moveable> map2;
+
+		for( std::pair < Moveable, Moveable > moveablePair : ext::make_mover (  multimap ) ) {
+			map2.insert(std::move(moveablePair));
+		}
+
+		CHECK ( copies == 0 );
+	}
+}