diff --git a/include/ebcl/Arrays.hh b/include/ebcl/Arrays.hh
index 8e52b51..7c5bf2f 100644
--- a/include/ebcl/Arrays.hh
+++ b/include/ebcl/Arrays.hh
@@ -285,92 +285,6 @@ class T_StaticArray final
 };
 
 
-/*= MULTI-ARRAYS ============================================================-*/
-/*
- * Arrays that allow storing multiple values for one entry. Values must be
- * added in order.
- */
-
-template< typename T >
-class T_MultiArray
-{
-   public:
-	using T_Data = T_Array< T >;
-
-   private:
-	typedef T_MultiArray< T > MyType_;
-
-	T_Array< uint32_t > meta_;
-	T_Data values_;
-
-   public:
-	M_TEMPLATE_POINTERS( T_MultiArray );
-
-	template< typename TP >
-	friend void swap( T_MultiArray< TP >& lhs , T_MultiArray< TP >& rhs );
-
-	// Start the next entry
-	void next( );
-	// Add a value to the current entry
-	void add( T value );
-	// Add a value, calling its constructor
-	template<
-		typename Q = T ,
-		typename... Args ,
-		typename = std::enable_if_t< std::is_class< Q >::value >
-		>
-	Q& addNew( Args&& ... args );
-	// Copy an array's contents into the current entry
-	void copyFrom( T_Data const& source );
-
-	// Returns the amount of entries
-	uint32_t size( ) const noexcept;
-	// Returns the index of the first value for an entry
-	uint32_t firstOf( uint32_t item ) const noexcept;
-	// Returns the amount of values for an entry
-	uint32_t sizeOf( uint32_t item ) const noexcept;
-	// Returns the amount of values across all entries
-	uint32_t values( ) const noexcept;
-
-	// Access a value in an entry
-	T const& get( uint32_t item , uint32_t sub ) const;
-	T& get( uint32_t item , uint32_t sub );
-
-	// Access a value using its index
-	T const& operator[] ( uint32_t index ) const;
-	T& operator[] ( uint32_t index );
-
-	// Is a value present in an entry?
-	bool contains( uint32_t index , T const& value ) const;
-
-	// Reset storage, don't free memory
-	void clear( );
-	// Reset storage and free memory
-	void free( );
-
-	// Copy values from an entry into the current entry
-	void copyFrom( uint32_t index );
-	// Copy another multi-array's entry into the current entry
-	void copyFrom( MyType_ const& other , uint32_t index );
-
-	// Copy values from another entry into the current entry if
-	// they are not already present. Duplicate entries in the
-	// source array are still copied, though.
-	void copyUnique( uint32_t index );
-	// Copy another multi-array's entry into the current entry,
-	// ignoring values that are already present. Duplicates in
-	// the source array are still copied.
-	void copyUnique( MyType_ const& other , uint32_t index );
-
-	// Sort an entry's values
-	void sort( uint32_t index , F_Comparator< T > cmp = T_Comparator< T >::compare );
-};
-
-
-// Instantiate some common types directly
-extern template class T_MultiArray< uint32_t >;
-
-
 /*= AUTOMATIC ARRAYS =========================================================*/
 /* Arrays that are stored in-place up to some limit, then transform into
  * dynamic arrays if necessary.
diff --git a/include/ebcl/MultiArrays.hh b/include/ebcl/MultiArrays.hh
new file mode 100644
index 0000000..b92fb62
--- /dev/null
+++ b/include/ebcl/MultiArrays.hh
@@ -0,0 +1,101 @@
+/******************************************************************************/
+/* MULTI-ARRAYS ***************************************************************/
+/******************************************************************************/
+
+#ifndef _H_EBCL_MULTIARRAYS
+#define _H_EBCL_MULTIARRAYS
+#include <ebcl/Arrays.hh>
+#include <ebcl/Strings.hh>
+namespace ebcl {
+
+
+/*= MULTI-ARRAYS ============================================================-*/
+/*
+ * Arrays that allow storing multiple values for one entry. Values must be
+ * added in order.
+ */
+
+template< typename T >
+class T_MultiArray
+{
+   public:
+	using T_Data = T_Array< T >;
+
+   private:
+	typedef T_MultiArray< T > MyType_;
+
+	T_Array< uint32_t > meta_;
+	T_Data values_;
+
+   public:
+	M_TEMPLATE_POINTERS( T_MultiArray );
+
+	template< typename TP >
+	friend void swap( T_MultiArray< TP >& lhs , T_MultiArray< TP >& rhs );
+
+	// Start the next entry
+	void next( );
+	// Add a value to the current entry
+	void add( T value );
+	// Add a value, calling its constructor
+	template<
+		typename Q = T ,
+		typename... Args ,
+		typename = std::enable_if_t< std::is_class< Q >::value >
+		>
+	Q& addNew( Args&& ... args );
+	// Copy an array's contents into the current entry
+	void copyFrom( T_Data const& source );
+
+	// Returns the amount of entries
+	uint32_t size( ) const noexcept;
+	// Returns the index of the first value for an entry
+	uint32_t firstOf( uint32_t item ) const noexcept;
+	// Returns the amount of values for an entry
+	uint32_t sizeOf( uint32_t item ) const noexcept;
+	// Returns the amount of values across all entries
+	uint32_t values( ) const noexcept;
+
+	// Access a value in an entry
+	T const& get( uint32_t item , uint32_t sub ) const;
+	T& get( uint32_t item , uint32_t sub );
+
+	// Access a value using its index
+	T const& operator[] ( uint32_t index ) const;
+	T& operator[] ( uint32_t index );
+
+	// Is a value present in an entry?
+	bool contains( uint32_t index , T const& value ) const;
+
+	// Reset storage, don't free memory
+	void clear( );
+	// Reset storage and free memory
+	void free( );
+
+	// Copy values from an entry into the current entry
+	void copyFrom( uint32_t index );
+	// Copy another multi-array's entry into the current entry
+	void copyFrom( MyType_ const& other , uint32_t index );
+
+	// Copy values from another entry into the current entry if
+	// they are not already present. Duplicate entries in the
+	// source array are still copied, though.
+	void copyUnique( uint32_t index );
+	// Copy another multi-array's entry into the current entry,
+	// ignoring values that are already present. Duplicates in
+	// the source array are still copied.
+	void copyUnique( MyType_ const& other , uint32_t index );
+
+	// Sort an entry's values
+	void sort( uint32_t index , F_Comparator< T > cmp = T_Comparator< T >::compare );
+};
+
+
+// Instantiate some common types directly
+extern template class T_MultiArray< uint32_t >;
+extern template class T_MultiArray< T_String >;
+
+
+}
+#endif // _H_EBCL_MULTIARRAYS
+#include <ebcl/inline/MultiArrays.hh>
diff --git a/include/ebcl/SRDParserConfig.hh b/include/ebcl/SRDParserConfig.hh
index 43c3f1b..117e6a9 100644
--- a/include/ebcl/SRDParserConfig.hh
+++ b/include/ebcl/SRDParserConfig.hh
@@ -4,6 +4,7 @@
 
 #ifndef _H_EBCL_SRDPARSERCONFIG
 #define _H_EBCL_SRDPARSERCONFIG
+#include <ebcl/MultiArrays.hh>
 #include <ebcl/SRDDefinitions.hh>
 #include <ebcl/Types.hh>
 namespace ebcl {
diff --git a/include/ebcl/Strings.hh b/include/ebcl/Strings.hh
index 9160b03..c85d0cd 100644
--- a/include/ebcl/Strings.hh
+++ b/include/ebcl/Strings.hh
@@ -307,7 +307,6 @@ M_DECLARE_COMPARATOR( T_String );
 void swap( T_String& lhs , T_String& rhs ) noexcept;
 
 extern template class T_Array< T_String >;
-extern template class T_MultiArray< T_String >;
 
 
 /*= STRING ITERATORS =========================================================*/
diff --git a/include/ebcl/inline/Arrays.hh b/include/ebcl/inline/Arrays.hh
index f4aaee5..ba0d1c6 100644
--- a/include/ebcl/inline/Arrays.hh
+++ b/include/ebcl/inline/Arrays.hh
@@ -1015,235 +1015,6 @@ inline T_StaticArray< T , S > T_StaticArray< T , S >::moveRange(
 #include "ebcl/bits/ArrayConstIterator.hh"
 
 
-/*= T_MultiArray ============================================================-*/
-
-template< typename T >
-inline void swap( T_MultiArray< T >& lhs , T_MultiArray< T >& rhs )
-{
-	using std::swap;
-	swap( lhs.meta_ , rhs.meta_ );
-	swap( lhs.values_ , rhs.values_ );
-}
-
-/*----------------------------------------------------------------------------*/
-
-template< typename T >
-inline void T_MultiArray< T >::next( )
-{
-	const auto sz( meta_.size( ) );
-	const auto first( ( sz == 0 ) ? 0 : ( meta_[ sz - 2 ] + meta_[ sz - 1 ] ) );
-	meta_ << first << 0;
-}
-
-template< typename T >
-inline void T_MultiArray< T >::add( T value )
-{
-	if ( meta_.size( ) == 0 ) {
-		meta_ << 0 << 1;
-	} else {
-		meta_[ meta_.size( ) - 1 ] ++;
-	}
-	values_ << value;
-}
-
-template< typename T >
-template<
-	typename Q ,
-	typename... Args ,
-	typename >
-inline Q& T_MultiArray< T >::addNew( Args&& ... args )
-{
-	if ( meta_.size( ) == 0 ) {
-		meta_ << 0 << 1;
-	} else {
-		meta_[ meta_.size( ) - 1 ] ++;
-	}
-	return values_.addNew( std::forward< Args >( args ) ... );
-}
-
-template< typename T >
-inline void T_MultiArray< T >::copyFrom( T_Array< T > const& source )
-{
-	values_.addAll( source );
-	if ( meta_.size( ) == 0 ) {
-		meta_ << 0 << source.size( );
-	} else {
-		meta_[ meta_.size( ) - 1 ] += source.size( );
-	}
-}
-
-/*----------------------------------------------------------------------------*/
-
-template< typename T >
-inline uint32_t T_MultiArray< T >::size( ) const noexcept
-{
-	return meta_.size( ) >> 1;
-}
-
-template< typename T >
-inline uint32_t T_MultiArray< T >::firstOf( uint32_t item ) const noexcept
-{
-	return meta_[ item * 2 ];
-}
-
-template< typename T >
-inline uint32_t T_MultiArray< T >::sizeOf( uint32_t item ) const noexcept
-{
-	return meta_[ item * 2 + 1 ];
-}
-
-template< typename T >
-inline uint32_t T_MultiArray< T >::values( ) const noexcept
-{
-	return values_.size( );
-}
-
-/*----------------------------------------------------------------------------*/
-
-template< typename T >
-inline T const& T_MultiArray< T >::get( uint32_t item , uint32_t sub ) const
-{
-	assert( sub < meta_[ item * 2 + 1 ] );
-	return values_[ meta_[ item * 2 ] + sub ];
-}
-
-template< typename T >
-inline T& T_MultiArray< T >::get( uint32_t item , uint32_t sub )
-{
-	assert( sub < meta_[ item * 2 + 1 ] );
-	return values_[ meta_[ item * 2 ] + sub ];
-}
-
-/*----------------------------------------------------------------------------*/
-
-template< typename T >
-inline T const& T_MultiArray< T >::operator[] ( uint32_t index ) const
-{
-	return values_[ index ];
-}
-
-template< typename T >
-inline T& T_MultiArray< T >::operator[] ( uint32_t index )
-{
-	return values_[ index ];
-}
-
-/*----------------------------------------------------------------------------*/
-
-template< typename T >
-inline bool T_MultiArray< T >::contains( uint32_t index , T const& value ) const
-{
-	const auto first( firstOf( index ) );
-	const auto end( first + sizeOf( index ) );
-	for ( uint32_t i = first ; i < end ; i ++ ) {
-		if ( values_[ i ] == value ) {
-			return true;
-		}
-	}
-	return false;
-}
-
-/*----------------------------------------------------------------------------*/
-
-template< typename T >
-inline void T_MultiArray< T >::clear( )
-{
-	meta_.clear( );
-	values_.clear( );
-}
-
-template< typename T >
-inline void T_MultiArray< T >::free( )
-{
-	meta_.free( );
-	values_.free( );
-}
-
-/*----------------------------------------------------------------------------*/
-
-template< typename T >
-inline void T_MultiArray< T >::copyFrom( uint32_t index )
-{
-	copyFrom( *this , index );
-}
-
-template< typename T >
-inline void T_MultiArray< T >::copyFrom(
-					T_MultiArray< T > const& other , uint32_t index )
-{
-	const auto size( other.sizeOf( index ) );
-	if ( size == 0 ) {
-		return;
-	}
-
-	const auto first( other.firstOf( index ) );
-	T const* ptr( &( other[ first ] ) );
-	for ( uint32_t i = 0 ; i < size ; i ++ , ptr ++ ) {
-		values_ << *ptr;
-	}
-	if ( meta_.size( ) == 0 ) {
-		meta_ << 0 << size;
-	} else {
-		meta_[ meta_.size( ) - 1 ] += size;
-	}
-}
-
-/*----------------------------------------------------------------------------*/
-
-template< typename T >
-inline void T_MultiArray< T >::copyUnique( uint32_t index )
-{
-	copyUnique( *this , index );
-}
-
-template< typename T >
-inline void T_MultiArray< T >::copyUnique( T_MultiArray< T > const& other , uint32_t index )
-{
-	const auto oSize( other.sizeOf( index ) );
-	if ( oSize == 0 ) {
-		return;
-	}
-
-	const auto ms( meta_.size( ) );
-	const auto tSize( ms == 0 ? 0 : meta_[ ms - 1 ] );
-	const auto tFirst( ms == 0 ? 0 : meta_[ ms - 2 ] );
-
-	const auto oFirst( other.firstOf( index ) );
-	T const* ptr( &( other[ oFirst ] ) );
-
-	uint32_t added = 0;
-	for ( uint32_t i = 0 ; i < oSize ; i ++ , ptr ++ ) {
-		bool found = false;
-		if ( tSize != 0 ) {
-			T const* pCheck( &values_[ tFirst ] );
-			for ( uint32_t j = 0 ; j < tSize ; j ++ , pCheck ++ ) {
-				if ( *pCheck == *ptr ) {
-					found = true;
-					break;
-				}
-			}
-		}
-		if ( !found ) {
-			values_ << *ptr;
-			added ++;
-		}
-	}
-	if ( ms == 0 ) {
-		meta_ << 0 << added;
-	} else {
-		meta_[ ms - 1 ] += added;
-	}
-}
-
-/*----------------------------------------------------------------------------*/
-
-template< typename T >
-inline void T_MultiArray< T >::sort( uint32_t index , F_Comparator< T > cmp )
-{
-	values_.sort( meta_[ index * 2 ] , meta_[ index * 2 + 1 ] , cmp );
-}
-
-
 /*= T_AutoArray ==============================================================*/
 
 template< typename T , uint32_t S , uint32_t G >
diff --git a/include/ebcl/inline/MultiArrays.hh b/include/ebcl/inline/MultiArrays.hh
new file mode 100644
index 0000000..a95dd02
--- /dev/null
+++ b/include/ebcl/inline/MultiArrays.hh
@@ -0,0 +1,241 @@
+/******************************************************************************/
+/* ARRAYS - INLINE CODE *******************************************************/
+/******************************************************************************/
+
+#ifndef _H_EBCL_INLINE_MULTIARRAYS
+#define _H_EBCL_INLINE_MULTIARRAYS
+#include <ebcl/MultiArrays.hh>
+namespace ebcl {
+
+
+/*= T_MultiArray ============================================================-*/
+
+template< typename T >
+inline void swap( T_MultiArray< T >& lhs , T_MultiArray< T >& rhs )
+{
+	using std::swap;
+	swap( lhs.meta_ , rhs.meta_ );
+	swap( lhs.values_ , rhs.values_ );
+}
+
+/*----------------------------------------------------------------------------*/
+
+template< typename T >
+inline void T_MultiArray< T >::next( )
+{
+	const auto sz( meta_.size( ) );
+	const auto first( ( sz == 0 ) ? 0 : ( meta_[ sz - 2 ] + meta_[ sz - 1 ] ) );
+	meta_ << first << 0;
+}
+
+template< typename T >
+inline void T_MultiArray< T >::add( T value )
+{
+	if ( meta_.size( ) == 0 ) {
+		meta_ << 0 << 1;
+	} else {
+		meta_[ meta_.size( ) - 1 ] ++;
+	}
+	values_ << value;
+}
+
+template< typename T >
+template<
+	typename Q ,
+	typename... Args ,
+	typename >
+inline Q& T_MultiArray< T >::addNew( Args&& ... args )
+{
+	if ( meta_.size( ) == 0 ) {
+		meta_ << 0 << 1;
+	} else {
+		meta_[ meta_.size( ) - 1 ] ++;
+	}
+	return values_.addNew( std::forward< Args >( args ) ... );
+}
+
+template< typename T >
+inline void T_MultiArray< T >::copyFrom( T_Array< T > const& source )
+{
+	values_.addAll( source );
+	if ( meta_.size( ) == 0 ) {
+		meta_ << 0 << source.size( );
+	} else {
+		meta_[ meta_.size( ) - 1 ] += source.size( );
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+
+template< typename T >
+inline uint32_t T_MultiArray< T >::size( ) const noexcept
+{
+	return meta_.size( ) >> 1;
+}
+
+template< typename T >
+inline uint32_t T_MultiArray< T >::firstOf( uint32_t item ) const noexcept
+{
+	return meta_[ item * 2 ];
+}
+
+template< typename T >
+inline uint32_t T_MultiArray< T >::sizeOf( uint32_t item ) const noexcept
+{
+	return meta_[ item * 2 + 1 ];
+}
+
+template< typename T >
+inline uint32_t T_MultiArray< T >::values( ) const noexcept
+{
+	return values_.size( );
+}
+
+/*----------------------------------------------------------------------------*/
+
+template< typename T >
+inline T const& T_MultiArray< T >::get( uint32_t item , uint32_t sub ) const
+{
+	assert( sub < meta_[ item * 2 + 1 ] );
+	return values_[ meta_[ item * 2 ] + sub ];
+}
+
+template< typename T >
+inline T& T_MultiArray< T >::get( uint32_t item , uint32_t sub )
+{
+	assert( sub < meta_[ item * 2 + 1 ] );
+	return values_[ meta_[ item * 2 ] + sub ];
+}
+
+/*----------------------------------------------------------------------------*/
+
+template< typename T >
+inline T const& T_MultiArray< T >::operator[] ( uint32_t index ) const
+{
+	return values_[ index ];
+}
+
+template< typename T >
+inline T& T_MultiArray< T >::operator[] ( uint32_t index )
+{
+	return values_[ index ];
+}
+
+/*----------------------------------------------------------------------------*/
+
+template< typename T >
+inline bool T_MultiArray< T >::contains( uint32_t index , T const& value ) const
+{
+	const auto first( firstOf( index ) );
+	const auto end( first + sizeOf( index ) );
+	for ( uint32_t i = first ; i < end ; i ++ ) {
+		if ( values_[ i ] == value ) {
+			return true;
+		}
+	}
+	return false;
+}
+
+/*----------------------------------------------------------------------------*/
+
+template< typename T >
+inline void T_MultiArray< T >::clear( )
+{
+	meta_.clear( );
+	values_.clear( );
+}
+
+template< typename T >
+inline void T_MultiArray< T >::free( )
+{
+	meta_.free( );
+	values_.free( );
+}
+
+/*----------------------------------------------------------------------------*/
+
+template< typename T >
+inline void T_MultiArray< T >::copyFrom( uint32_t index )
+{
+	copyFrom( *this , index );
+}
+
+template< typename T >
+inline void T_MultiArray< T >::copyFrom(
+					T_MultiArray< T > const& other , uint32_t index )
+{
+	const auto size( other.sizeOf( index ) );
+	if ( size == 0 ) {
+		return;
+	}
+
+	const auto first( other.firstOf( index ) );
+	T const* ptr( &( other[ first ] ) );
+	for ( uint32_t i = 0 ; i < size ; i ++ , ptr ++ ) {
+		values_ << *ptr;
+	}
+	if ( meta_.size( ) == 0 ) {
+		meta_ << 0 << size;
+	} else {
+		meta_[ meta_.size( ) - 1 ] += size;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+
+template< typename T >
+inline void T_MultiArray< T >::copyUnique( uint32_t index )
+{
+	copyUnique( *this , index );
+}
+
+template< typename T >
+inline void T_MultiArray< T >::copyUnique( T_MultiArray< T > const& other , uint32_t index )
+{
+	const auto oSize( other.sizeOf( index ) );
+	if ( oSize == 0 ) {
+		return;
+	}
+
+	const auto ms( meta_.size( ) );
+	const auto tSize( ms == 0 ? 0 : meta_[ ms - 1 ] );
+	const auto tFirst( ms == 0 ? 0 : meta_[ ms - 2 ] );
+
+	const auto oFirst( other.firstOf( index ) );
+	T const* ptr( &( other[ oFirst ] ) );
+
+	uint32_t added = 0;
+	for ( uint32_t i = 0 ; i < oSize ; i ++ , ptr ++ ) {
+		bool found = false;
+		if ( tSize != 0 ) {
+			T const* pCheck( &values_[ tFirst ] );
+			for ( uint32_t j = 0 ; j < tSize ; j ++ , pCheck ++ ) {
+				if ( *pCheck == *ptr ) {
+					found = true;
+					break;
+				}
+			}
+		}
+		if ( !found ) {
+			values_ << *ptr;
+			added ++;
+		}
+	}
+	if ( ms == 0 ) {
+		meta_ << 0 << added;
+	} else {
+		meta_[ ms - 1 ] += added;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+
+template< typename T >
+inline void T_MultiArray< T >::sort( uint32_t index , F_Comparator< T > cmp )
+{
+	values_.sort( meta_[ index * 2 ] , meta_[ index * 2 + 1 ] , cmp );
+}
+
+
+} // namespace
+#endif // _H_EBCL_INLINE_MULTIARRAYS
diff --git a/src/TemplateInstantiation.cc b/src/TemplateInstantiation.cc
index 338bdaa..957915a 100644
--- a/src/TemplateInstantiation.cc
+++ b/src/TemplateInstantiation.cc
@@ -4,6 +4,7 @@
 
 #include <ebcl/Utilities.hh>
 #include <ebcl/Arrays.hh>
+#include <ebcl/MultiArrays.hh>
 #include <ebcl/Strings.hh>
 #include <ebcl/SRDData.hh>
 #include <ebcl/SRDDefinitions.hh>
diff --git a/tests/arrays-multi.cc b/tests/arrays-multi.cc
index 1db4da1..5b6bd8f 100644
--- a/tests/arrays-multi.cc
+++ b/tests/arrays-multi.cc
@@ -1,4 +1,4 @@
-#include <ebcl/Arrays.hh>
+#include <ebcl/MultiArrays.hh>
 #include <cppunit/extensions/HelperMacros.h>
 using namespace ebcl;