diff --git a/transcoder/basisu_containers.h b/transcoder/basisu_containers.h
new file mode 100644
index 0000000..a42bde9
--- /dev/null
+++ b/transcoder/basisu_containers.h
@@ -0,0 +1,1875 @@
+// basisu_containers.h
+#pragma once
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <assert.h>
+#include <algorithm>
+#include <malloc.h>
+
+#ifdef _MSC_VER
+#define BASISU_FORCE_INLINE __forceinline
+#else
+#define BASISU_FORCE_INLINE inline
+#endif
+
+namespace basisu
+{
+   enum { cInvalidIndex = -1 };
+
+   namespace helpers
+   {
+      inline bool is_power_of_2(uint32_t x) { return x && ((x & (x - 1U)) == 0U); }
+      inline bool is_power_of_2(uint64_t x) { return x && ((x & (x - 1U)) == 0U); }
+
+      inline uint32_t floor_log2i(uint32_t v)
+      {
+         uint32_t l = 0;
+         while (v > 1U)
+         {
+            v >>= 1;
+            l++;
+         }
+         return l;
+      }
+
+      inline uint32_t next_pow2(uint32_t val)
+      {
+         val--;
+         val |= val >> 16;
+         val |= val >> 8;
+         val |= val >> 4;
+         val |= val >> 2;
+         val |= val >> 1;
+         return val + 1;
+      }
+
+      inline uint64_t next_pow2(uint64_t val)
+      {
+         val--;
+         val |= val >> 32;
+         val |= val >> 16;
+         val |= val >> 8;
+         val |= val >> 4;
+         val |= val >> 2;
+         val |= val >> 1;
+         return val + 1;
+      }
+   } // namespace helpers
+
+   template <typename T>
+   inline T* construct(T* p)
+   {
+      return new (static_cast<void*>(p)) T;
+   }
+
+   template <typename T, typename U>
+   inline T* construct(T* p, const U& init)
+   {
+      return new (static_cast<void*>(p)) T(init);
+   }
+
+   template <typename T>
+   inline void construct_array(T* p, size_t n)
+   {
+      T* q = p + n;
+      for (; p != q; ++p)
+         new (static_cast<void*>(p)) T;
+   }
+
+   template <typename T, typename U>
+   inline void construct_array(T* p, size_t n, const U& init)
+   {
+      T* q = p + n;
+      for (; p != q; ++p)
+         new (static_cast<void*>(p)) T(init);
+   }
+
+   template <typename T>
+   inline void destruct(T* p)
+   {
+      (void)p;
+      p->~T();
+   }
+
+   template <typename T> inline void destruct_array(T* p, size_t n)
+   {
+      T* q = p + n;
+      for (; p != q; ++p)
+         p->~T();
+   }
+
+   template<typename T> struct int_traits { enum { cMin = INT32_MIN, cMax = INT32_MAX, cSigned = true }; };
+
+   template<> struct int_traits<int8_t> { enum { cMin = INT8_MIN, cMax = INT8_MAX, cSigned = true }; };
+   template<> struct int_traits<int16_t> { enum { cMin = INT16_MIN, cMax = INT16_MAX, cSigned = true }; };
+   template<> struct int_traits<int32_t> { enum { cMin = INT32_MIN, cMax = INT32_MAX, cSigned = true }; };
+
+   template<> struct int_traits<uint8_t> { enum { cMin = 0, cMax = UINT8_MAX, cSigned = false }; };
+   template<> struct int_traits<uint16_t> { enum { cMin = 0, cMax = UINT16_MAX, cSigned = false }; };
+   template<> struct int_traits<uint32_t> { enum { cMin = 0, cMax = UINT32_MAX, cSigned = false }; };
+
+   template<typename T>
+   struct scalar_type
+   {
+      enum { cFlag = false };
+      static inline void construct(T* p) { basisu::construct(p); }
+      static inline void construct(T* p, const T& init) { basisu::construct(p, init); }
+      static inline void construct_array(T* p, size_t n) { basisu::construct_array(p, n); }
+      static inline void destruct(T* p) { basisu::destruct(p); }
+      static inline void destruct_array(T* p, size_t n) { basisu::destruct_array(p, n); }
+   };
+
+   template<typename T> struct scalar_type<T*>
+   {
+      enum { cFlag = true };
+      static inline void construct(T** p) { memset(p, 0, sizeof(T*)); }
+      static inline void construct(T** p, T* init) { *p = init; }
+      static inline void construct_array(T** p, size_t n) { memset(p, 0, sizeof(T*) * n); }
+      static inline void destruct(T** p) { p; }
+      static inline void destruct_array(T** p, size_t n) { p, n; }
+   };
+
+#define BASISU_DEFINE_BUILT_IN_TYPE(X) \
+   template<> struct scalar_type<X> { \
+   enum { cFlag = true }; \
+   static inline void construct(X* p) { memset(p, 0, sizeof(X)); } \
+   static inline void construct(X* p, const X& init) { memcpy(p, &init, sizeof(X)); } \
+   static inline void construct_array(X* p, size_t n) { memset(p, 0, sizeof(X) * n); } \
+   static inline void destruct(X* p) { p; } \
+   static inline void destruct_array(X* p, size_t n) { p, n; } };
+
+   BASISU_DEFINE_BUILT_IN_TYPE(bool)
+   BASISU_DEFINE_BUILT_IN_TYPE(char)
+   BASISU_DEFINE_BUILT_IN_TYPE(unsigned char)
+   BASISU_DEFINE_BUILT_IN_TYPE(short)
+   BASISU_DEFINE_BUILT_IN_TYPE(unsigned short)
+   BASISU_DEFINE_BUILT_IN_TYPE(int)
+   BASISU_DEFINE_BUILT_IN_TYPE(unsigned int)
+   BASISU_DEFINE_BUILT_IN_TYPE(long)
+   BASISU_DEFINE_BUILT_IN_TYPE(unsigned long)
+#ifdef __GNUC__
+   BASISU_DEFINE_BUILT_IN_TYPE(long long)
+   BASISU_DEFINE_BUILT_IN_TYPE(unsigned long long)
+#else
+   BASISU_DEFINE_BUILT_IN_TYPE(__int64)
+   BASISU_DEFINE_BUILT_IN_TYPE(unsigned __int64)
+#endif
+   BASISU_DEFINE_BUILT_IN_TYPE(float)
+   BASISU_DEFINE_BUILT_IN_TYPE(double)
+   BASISU_DEFINE_BUILT_IN_TYPE(long double)
+
+#undef BASISU_DEFINE_BUILT_IN_TYPE
+
+   template<typename T>
+   struct bitwise_movable { enum { cFlag = false }; };
+
+#define BASISU_DEFINE_BITWISE_MOVABLE(Q) template<> struct bitwise_movable<Q> { enum { cFlag = true }; };
+
+   template<typename T>
+   struct bitwise_copyable { enum { cFlag = false }; };
+
+#define BASISU_DEFINE_BITWISE_COPYABLE(Q) template<> struct bitwise_copyable<Q> { enum { cFlag = true }; };
+
+#define BASISU_IS_POD(T) __is_pod(T)
+
+#define BASISU_IS_SCALAR_TYPE(T) (scalar_type<T>::cFlag)
+
+#if defined(__GNUC__) && __GNUC__<5
+   #define BASISU_IS_TRIVIALLY_COPYABLE(...) __has_trivial_copy(__VA_ARGS__)
+#else
+   #define BASISU_IS_TRIVIALLY_COPYABLE(...) std::is_trivially_copyable<__VA_ARGS__>::value
+#endif
+
+// TODO: clean this up
+#define BASISU_IS_BITWISE_COPYABLE(T) (BASISU_IS_SCALAR_TYPE(T) || BASISU_IS_POD(T) || BASISU_IS_TRIVIALLY_COPYABLE(T) || (bitwise_copyable<T>::cFlag))
+
+#define BASISU_IS_BITWISE_COPYABLE_OR_MOVABLE(T) (BASISU_IS_BITWISE_COPYABLE(T) || (bitwise_movable<T>::cFlag))
+
+#define BASISU_HAS_DESTRUCTOR(T) ((!scalar_type<T>::cFlag) && (!__is_pod(T)))
+
+   typedef char(&yes_t)[1];
+   typedef char(&no_t)[2];
+
+   template <class U> yes_t class_test(int U::*);
+   template <class U> no_t class_test(...);
+
+   template <class T> struct is_class
+   {
+      enum { value = (sizeof(class_test<T>(0)) == sizeof(yes_t)) };
+   };
+
+   template <typename T> struct is_pointer
+   {
+      enum { value = false };
+   };
+
+   template <typename T> struct is_pointer<T*>
+   {
+      enum { value = true };
+   };
+
+   struct empty_type { };
+
+   BASISU_DEFINE_BITWISE_COPYABLE(empty_type);
+   BASISU_DEFINE_BITWISE_MOVABLE(empty_type);
+
+   template<typename T> struct rel_ops
+   {
+      friend bool operator!=(const T& x, const T& y) { return (!(x == y)); }
+      friend bool operator> (const T& x, const T& y) { return (y < x); }
+      friend bool operator<=(const T& x, const T& y) { return (!(y < x)); }
+      friend bool operator>=(const T& x, const T& y) { return (!(x < y)); }
+   };
+
+   struct elemental_vector
+   {
+      void* m_p;
+      uint32_t m_size;
+      uint32_t m_capacity;
+
+      typedef void (*object_mover)(void* pDst, void* pSrc, uint32_t num);
+
+      bool increase_capacity(uint32_t min_new_capacity, bool grow_hint, uint32_t element_size, object_mover pRelocate, bool nofail);
+   };
+
+   template<typename T>
+   class vector : public rel_ops< vector<T> >
+   {
+   public:
+      typedef T* iterator;
+      typedef const T* const_iterator;
+      typedef T value_type;
+      typedef T& reference;
+      typedef const T& const_reference;
+      typedef T* pointer;
+      typedef const T* const_pointer;
+
+      inline vector() :
+         m_p(NULL),
+         m_size(0),
+         m_capacity(0)
+      {
+      }
+
+      inline vector(uint32_t n, const T& init) :
+         m_p(NULL),
+         m_size(0),
+         m_capacity(0)
+      {
+         increase_capacity(n, false);
+         construct_array(m_p, n, init);
+         m_size = n;
+      }
+
+      inline vector(const vector& other) :
+         m_p(NULL),
+         m_size(0),
+         m_capacity(0)
+      {
+         increase_capacity(other.m_size, false);
+
+         m_size = other.m_size;
+
+         if (BASISU_IS_BITWISE_COPYABLE(T))
+            memcpy(m_p, other.m_p, m_size * sizeof(T));
+         else
+         {
+            T* pDst = m_p;
+            const T* pSrc = other.m_p;
+            for (uint32_t i = m_size; i > 0; i--)
+               construct(pDst++, *pSrc++);
+         }
+      }
+
+      inline explicit vector(size_t size) :
+         m_p(NULL),
+         m_size(0),
+         m_capacity(0)
+      {
+         resize(size);
+      }
+
+      inline ~vector()
+      {
+         if (m_p)
+         {
+            scalar_type<T>::destruct_array(m_p, m_size);
+            free(m_p);
+         }
+      }
+
+      inline vector& operator= (const vector& other)
+      {
+         if (this == &other)
+            return *this;
+
+         if (m_capacity >= other.m_size)
+            resize(0);
+         else
+         {
+            clear();
+            increase_capacity(other.m_size, false);
+         }
+
+         if (BASISU_IS_BITWISE_COPYABLE(T))
+            memcpy(m_p, other.m_p, other.m_size * sizeof(T));
+         else
+         {
+            T* pDst = m_p;
+            const T* pSrc = other.m_p;
+            for (uint32_t i = other.m_size; i > 0; i--)
+               construct(pDst++, *pSrc++);
+         }
+
+         m_size = other.m_size;
+
+         return *this;
+      }
+
+      BASISU_FORCE_INLINE const T* begin() const { return m_p; }
+      BASISU_FORCE_INLINE T* begin() { return m_p; }
+
+      BASISU_FORCE_INLINE const T* end() const { return m_p + m_size; }
+      BASISU_FORCE_INLINE T* end() { return m_p + m_size; }
+
+      BASISU_FORCE_INLINE bool empty() const { return !m_size; }
+      BASISU_FORCE_INLINE uint32_t size() const { return m_size; }
+      BASISU_FORCE_INLINE uint32_t size_in_bytes() const { return m_size * sizeof(T); }
+      BASISU_FORCE_INLINE uint32_t capacity() const { return m_capacity; }
+
+      // operator[] will assert on out of range indices, but in final builds there is (and will never be) any range checking on this method.
+      //BASISU_FORCE_INLINE const T& operator[] (uint32_t i) const { assert(i < m_size); return m_p[i]; }
+      //BASISU_FORCE_INLINE T& operator[] (uint32_t i) { assert(i < m_size); return m_p[i]; }
+
+      BASISU_FORCE_INLINE const T& operator[] (size_t i) const { assert(i < m_size); return m_p[i]; }
+      BASISU_FORCE_INLINE T& operator[] (size_t i) { assert(i < m_size); return m_p[i]; }
+
+      // at() always includes range checking, even in final builds, unlike operator [].
+      // The first element is returned if the index is out of range.
+      BASISU_FORCE_INLINE const T& at(size_t i) const { assert(i < m_size); return (i >= m_size) ? m_p[0] : m_p[i]; }
+      BASISU_FORCE_INLINE T& at(size_t i) { assert(i < m_size); return (i >= m_size) ? m_p[0] : m_p[i]; }
+
+      BASISU_FORCE_INLINE const T& front() const { assert(m_size); return m_p[0]; }
+      BASISU_FORCE_INLINE T& front() { assert(m_size); return m_p[0]; }
+
+      BASISU_FORCE_INLINE const T& back() const { assert(m_size); return m_p[m_size - 1]; }
+      BASISU_FORCE_INLINE T& back() { assert(m_size); return m_p[m_size - 1]; }
+
+      BASISU_FORCE_INLINE const T* get_ptr() const { return m_p; }
+      BASISU_FORCE_INLINE T* get_ptr() { return m_p; }
+
+      BASISU_FORCE_INLINE const T* data() const { return m_p; }
+      BASISU_FORCE_INLINE T* data() { return m_p; }
+
+      // clear() sets the container to empty, then frees the allocated block.
+      inline void clear()
+      {
+         if (m_p)
+         {
+            scalar_type<T>::destruct_array(m_p, m_size);
+            free(m_p);
+            m_p = NULL;
+            m_size = 0;
+            m_capacity = 0;
+         }
+      }
+
+      inline void clear_no_destruction()
+      {
+         if (m_p)
+         {
+            free(m_p);
+            m_p = NULL;
+            m_size = 0;
+            m_capacity = 0;
+         }
+      }
+
+      inline void reserve(size_t new_capacity_size_t)
+      {
+         if (new_capacity_size_t > UINT32_MAX)
+         {
+            assert(0);
+            return;
+         }
+
+         uint32_t new_capacity = (uint32_t)new_capacity_size_t;
+
+         if (new_capacity > m_capacity)
+            increase_capacity(new_capacity, false);
+         else if (new_capacity < m_capacity)
+         {
+            // Must work around the lack of a "decrease_capacity()" method.
+            // This case is rare enough in practice that it's probably not worth implementing an optimized in-place resize.
+            vector tmp;
+            tmp.increase_capacity(std::max(m_size, new_capacity), false);
+            tmp = *this;
+            swap(tmp);
+         }
+      }
+
+      inline bool try_reserve(size_t new_capacity)
+      {
+         return increase_capacity(new_capacity, true, true);
+      }
+
+      // resize(0) sets the container to empty, but does not free the allocated block.
+      inline void resize(size_t new_size_size_t, bool grow_hint = false)
+      {
+         if (new_size_size_t > UINT32_MAX)
+         {
+            assert(0);
+            return;
+         }
+
+         uint32_t new_size = (uint32_t)new_size_size_t;
+
+         if (m_size != new_size)
+         {
+            if (new_size < m_size)
+               scalar_type<T>::destruct_array(m_p + new_size, m_size - new_size);
+            else
+            {
+               if (new_size > m_capacity)
+                  increase_capacity(new_size, (new_size == (m_size + 1)) || grow_hint);
+
+               scalar_type<T>::construct_array(m_p + m_size, new_size - m_size);
+            }
+
+            m_size = new_size;
+         }
+      }
+
+      inline bool try_resize(size_t new_size_size_t, bool grow_hint = false)
+      {
+         if (new_size_size_t > UINT32_MAX)
+         {
+            assert(0);
+            return false;
+         }
+
+         uint32_t new_size = (uint32_t)new_size_size_t;
+
+         if (m_size != new_size)
+         {
+            if (new_size < m_size)
+               scalar_type<T>::destruct_array(m_p + new_size, m_size - new_size);
+            else
+            {
+               if (new_size > m_capacity)
+               {
+                  if (!increase_capacity(new_size, (new_size == (m_size + 1)) || grow_hint, true))
+                     return false;
+               }
+
+               scalar_type<T>::construct_array(m_p + m_size, new_size - m_size);
+            }
+
+            m_size = new_size;
+         }
+
+         return true;
+      }
+
+      // If size >= capacity/2, reset() sets the container's size to 0 but doesn't free the allocated block (because the container may be similarly loaded in the future).
+      // Otherwise it blows away the allocated block. See http://www.codercorner.com/blog/?p=494
+      inline void reset()
+      {
+         if (m_size >= (m_capacity >> 1))
+            resize(0);
+         else
+            clear();
+      }
+
+      inline T* enlarge(uint32_t i)
+      {
+         uint32_t cur_size = m_size;
+         resize(cur_size + i, true);
+         return get_ptr() + cur_size;
+      }
+
+      inline T* try_enlarge(uint32_t i)
+      {
+         uint32_t cur_size = m_size;
+         if (!try_resize(cur_size + i, true))
+            return NULL;
+         return get_ptr() + cur_size;
+      }
+
+      BASISU_FORCE_INLINE void push_back(const T& obj)
+      {
+         assert(!m_p || (&obj < m_p) || (&obj >= (m_p + m_size)));
+
+         if (m_size >= m_capacity)
+            increase_capacity(m_size + 1, true);
+
+         scalar_type<T>::construct(m_p + m_size, obj);
+         m_size++;
+      }
+
+      inline bool try_push_back(const T& obj)
+      {
+         assert(!m_p || (&obj < m_p) || (&obj >= (m_p + m_size)));
+
+         if (m_size >= m_capacity)
+         {
+            if (!increase_capacity(m_size + 1, true, true))
+               return false;
+         }
+
+         scalar_type<T>::construct(m_p + m_size, obj);
+         m_size++;
+
+         return true;
+      }
+
+      inline void push_back_value(T obj)
+      {
+         if (m_size >= m_capacity)
+            increase_capacity(m_size + 1, true);
+
+         scalar_type<T>::construct(m_p + m_size, obj);
+         m_size++;
+      }
+
+      inline void pop_back()
+      {
+         assert(m_size);
+
+         if (m_size)
+         {
+            m_size--;
+            scalar_type<T>::destruct(&m_p[m_size]);
+         }
+      }
+
+      inline void insert(uint32_t index, const T* p, uint32_t n)
+      {
+         assert(index <= m_size);
+         if (!n)
+            return;
+
+         const uint32_t orig_size = m_size;
+         resize(m_size + n, true);
+
+         const uint32_t num_to_move = orig_size - index;
+
+         if (BASISU_IS_BITWISE_COPYABLE(T))
+         {
+            // This overwrites the destination object bits, but bitwise copyable means we don't need to worry about destruction.
+            memmove(m_p + index + n, m_p + index, sizeof(T) * num_to_move);
+         }
+         else
+         {
+            const T* pSrc = m_p + orig_size - 1;
+            T* pDst = const_cast<T*>(pSrc) + n;
+
+            for (uint32_t i = 0; i < num_to_move; i++)
+            {
+               assert((pDst - m_p) < (int)m_size);
+               *pDst-- = *pSrc--;
+            }
+         }
+
+         T* pDst = m_p + index;
+
+         if (BASISU_IS_BITWISE_COPYABLE(T))
+         {
+            // This copies in the new bits, overwriting the existing objects, which is OK for copyable types that don't need destruction.
+            memcpy(pDst, p, sizeof(T) * n);
+         }
+         else
+         {
+            for (uint32_t i = 0; i < n; i++)
+            {
+               assert((pDst - m_p) < (int)m_size);
+               *pDst++ = *p++;
+            }
+         }
+      }
+
+      inline void insert(T* p, const T& obj)
+      {
+         int64_t ofs = p - begin();
+         if ((ofs < 0) || (ofs > UINT32_MAX))
+         {
+            assert(0);
+            return;
+         }
+
+         insert((uint32_t)ofs, &obj, 1);
+      }
+
+      // push_front() isn't going to be very fast - it's only here for usability.
+      inline void push_front(const T& obj)
+      {
+         insert(0, &obj, 1);
+      }
+
+      vector& append(const vector& other)
+      {
+         if (other.m_size)
+            insert(m_size, &other[0], other.m_size);
+         return *this;
+      }
+
+      vector& append(const T* p, uint32_t n)
+      {
+         if (n)
+            insert(m_size, p, n);
+         return *this;
+      }
+            
+      inline void erase(uint32_t start, uint32_t n)
+      {
+         assert((start + n) <= m_size);
+         if ((start + n) > m_size)
+            return;
+
+         if (!n)
+            return;
+
+         const uint32_t num_to_move = m_size - (start + n);
+
+         T* pDst = m_p + start;
+
+         const T* pSrc = m_p + start + n;
+
+         if (BASISU_IS_BITWISE_COPYABLE_OR_MOVABLE(T))
+         {
+            // This test is overly cautious.
+            if ((!BASISU_IS_BITWISE_COPYABLE(T)) || (BASISU_HAS_DESTRUCTOR(T)))
+            {
+               // Type has been marked explictly as bitwise movable, which means we can move them around but they may need to be destructed.
+               // First destroy the erased objects.
+               scalar_type<T>::destruct_array(pDst, n);
+            }
+
+            // Copy "down" the objects to preserve, filling in the empty slots.
+            memmove(pDst, pSrc, num_to_move * sizeof(T));
+         }
+         else
+         {
+            // Type is not bitwise copyable or movable. 
+            // Move them down one at a time by using the equals operator, and destroying anything that's left over at the end.
+            T* pDst_end = pDst + num_to_move;
+            while (pDst != pDst_end)
+               *pDst++ = *pSrc++;
+
+            scalar_type<T>::destruct_array(pDst_end, n);
+         }
+
+         m_size -= n;
+      }
+
+      inline void erase(uint32_t index)
+      {
+         erase(index, 1);
+      }
+
+      inline void erase(T* p)
+      {
+         assert((p >= m_p) && (p < (m_p + m_size)));
+         erase(static_cast<uint32_t>(p - m_p));
+      }
+
+      inline void erase(T *pFirst, T *pEnd)
+      {
+         assert(pFirst <= pEnd);
+         assert(pFirst >= begin() && pFirst <= end());
+         assert(pEnd >= begin() && pEnd <= end());
+
+         int64_t ofs = pFirst - begin();
+         if ((ofs < 0) || (ofs > UINT32_MAX))
+         {
+            assert(0);
+            return;
+         }
+
+         int64_t n = pEnd - pFirst;
+         if ((n < 0) || (n > UINT32_MAX))
+         {
+            assert(0);
+            return;
+         }
+
+         erase((uint32_t)ofs, (uint32_t)n);
+      }
+
+      void erase_unordered(uint32_t index)
+      {
+         assert(index < m_size);
+
+         if ((index + 1) < m_size)
+            (*this)[index] = back();
+
+         pop_back();
+      }
+
+      inline bool operator== (const vector& rhs) const
+      {
+         if (m_size != rhs.m_size)
+            return false;
+         else if (m_size)
+         {
+            if (scalar_type<T>::cFlag)
+               return memcmp(m_p, rhs.m_p, sizeof(T) * m_size) == 0;
+            else
+            {
+               const T* pSrc = m_p;
+               const T* pDst = rhs.m_p;
+               for (uint32_t i = m_size; i; i--)
+                  if (!(*pSrc++ == *pDst++))
+                     return false;
+            }
+         }
+
+         return true;
+      }
+
+      inline bool operator< (const vector& rhs) const
+      {
+         const uint32_t min_size = std::min(m_size, rhs.m_size);
+
+         const T* pSrc = m_p;
+         const T* pSrc_end = m_p + min_size;
+         const T* pDst = rhs.m_p;
+
+         while ((pSrc < pSrc_end) && (*pSrc == *pDst))
+         {
+            pSrc++;
+            pDst++;
+         }
+
+         if (pSrc < pSrc_end)
+            return *pSrc < *pDst;
+
+         return m_size < rhs.m_size;
+      }
+
+      inline void swap(vector& other)
+      {
+         std::swap(m_p, other.m_p);
+         std::swap(m_size, other.m_size);
+         std::swap(m_capacity, other.m_capacity);
+      }
+
+      inline void sort()
+      {
+         std::sort(begin(), end());
+      }
+
+      inline void unique()
+      {
+         if (!empty())
+         {
+            sort();
+
+            resize(std::unique(begin(), end()) - begin());
+         }
+      }
+
+      inline void reverse()
+      {
+         uint32_t j = m_size >> 1;
+         for (uint32_t i = 0; i < j; i++)
+            std::swap(m_p[i], m_p[m_size - 1 - i]);
+      }
+
+      inline int find(const T& key) const
+      {
+         const T* p = m_p;
+         const T* p_end = m_p + m_size;
+
+         uint32_t index = 0;
+
+         while (p != p_end)
+         {
+            if (key == *p)
+               return index;
+
+            p++;
+            index++;
+         }
+
+         return cInvalidIndex;
+      }
+
+      inline int find_sorted(const T& key) const
+      {
+         if (m_size)
+         {
+            // Uniform binary search - Knuth Algorithm 6.2.1 U, unrolled twice.
+            int i = ((m_size + 1) >> 1) - 1;
+            int m = m_size;
+
+            for (; ; )
+            {
+               assert(i >= 0 && i < (int)m_size);
+               const T* pKey_i = m_p + i;
+               int cmp = key < *pKey_i;
+#if defined(_DEBUG) || defined(DEBUG)
+               int cmp2 = *pKey_i < key;
+               assert((cmp != cmp2) || (key == *pKey_i));
+#endif
+               if ((!cmp) && (key == *pKey_i)) return i;
+               m >>= 1;
+               if (!m) break;
+               cmp = -cmp;
+               i += (((m + 1) >> 1) ^ cmp) - cmp;
+               if (i < 0)
+                  break;
+
+               assert(i >= 0 && i < (int)m_size);
+               pKey_i = m_p + i;
+               cmp = key < *pKey_i;
+#if defined(_DEBUG) || defined(DEBUG)
+               cmp2 = *pKey_i < key;
+               assert((cmp != cmp2) || (key == *pKey_i));
+#endif
+               if ((!cmp) && (key == *pKey_i)) return i;
+               m >>= 1;
+               if (!m) break;
+               cmp = -cmp;
+               i += (((m + 1) >> 1) ^ cmp) - cmp;
+               if (i < 0)
+                  break;
+            }
+         }
+
+         return cInvalidIndex;
+      }
+
+      template<typename Q>
+      inline int find_sorted(const T& key, Q less_than) const
+      {
+         if (m_size)
+         {
+            // Uniform binary search - Knuth Algorithm 6.2.1 U, unrolled twice.
+            int i = ((m_size + 1) >> 1) - 1;
+            int m = m_size;
+
+            for (; ; )
+            {
+               assert(i >= 0 && i < (int)m_size);
+               const T* pKey_i = m_p + i;
+               int cmp = less_than(key, *pKey_i);
+               if ((!cmp) && (!less_than(*pKey_i, key))) return i;
+               m >>= 1;
+               if (!m) break;
+               cmp = -cmp;
+               i += (((m + 1) >> 1) ^ cmp) - cmp;
+               if (i < 0)
+                  break;
+
+               assert(i >= 0 && i < (int)m_size);
+               pKey_i = m_p + i;
+               cmp = less_than(key, *pKey_i);
+               if ((!cmp) && (!less_than(*pKey_i, key))) return i;
+               m >>= 1;
+               if (!m) break;
+               cmp = -cmp;
+               i += (((m + 1) >> 1) ^ cmp) - cmp;
+               if (i < 0) 
+                  break;
+            }
+         }
+
+         return cInvalidIndex;
+      }
+
+      inline uint32_t count_occurences(const T& key) const
+      {
+         uint32_t c = 0;
+
+         const T* p = m_p;
+         const T* p_end = m_p + m_size;
+
+         while (p != p_end)
+         {
+            if (key == *p)
+               c++;
+
+            p++;
+         }
+
+         return c;
+      }
+
+      inline void set_all(const T& o)
+      {
+         if ((sizeof(T) == 1) && (scalar_type<T>::cFlag))
+            memset(m_p, *reinterpret_cast<const uint8_t*>(&o), m_size);
+         else
+         {
+            T* pDst = m_p;
+            T* pDst_end = pDst + m_size;
+            while (pDst != pDst_end)
+               *pDst++ = o;
+         }
+      }
+
+      // Caller assumes ownership of the heap block associated with the container. Container is cleared.
+      inline void* assume_ownership()
+      {
+         T* p = m_p;
+         m_p = NULL;
+         m_size = 0;
+         m_capacity = 0;
+         return p;
+      }
+
+      // Caller is granting ownership of the indicated heap block.
+      // Block must have size constructed elements, and have enough room for capacity elements.
+      inline bool grant_ownership(T* p, uint32_t size, uint32_t capacity)
+      {
+         // To to prevent the caller from obviously shooting themselves in the foot.
+         if (((p + capacity) > m_p) && (p < (m_p + m_capacity)))
+         {
+            // Can grant ownership of a block inside the container itself!
+            assert(0);
+            return false;
+         }
+
+         if (size > capacity)
+         {
+            assert(0);
+            return false;
+         }
+
+         if (!p)
+         {
+            if (capacity)
+            {
+               assert(0);
+               return false;
+            }
+         }
+         else if (!capacity)
+         {
+            assert(0);
+            return false;
+         }
+
+         clear();
+         m_p = p;
+         m_size = size;
+         m_capacity = capacity;
+         return true;
+      }
+
+   private:
+      T* m_p;
+      uint32_t m_size;
+      uint32_t m_capacity;
+
+      template<typename Q> struct is_vector { enum { cFlag = false }; };
+      template<typename Q> struct is_vector< vector<Q> > { enum { cFlag = true }; };
+
+      static void object_mover(void* pDst_void, void* pSrc_void, uint32_t num)
+      {
+         T* pSrc = static_cast<T*>(pSrc_void);
+         T* const pSrc_end = pSrc + num;
+         T* pDst = static_cast<T*>(pDst_void);
+
+         while (pSrc != pSrc_end)
+         {
+            // placement new
+            new (static_cast<void*>(pDst)) T(*pSrc);
+            pSrc->~T();
+            ++pSrc;
+            ++pDst;
+         }
+      }
+
+      inline bool increase_capacity(uint32_t min_new_capacity, bool grow_hint, bool nofail = false)
+      {
+         return reinterpret_cast<elemental_vector*>(this)->increase_capacity(
+            min_new_capacity, grow_hint, sizeof(T),
+            (BASISU_IS_BITWISE_COPYABLE_OR_MOVABLE(T) || (is_vector<T>::cFlag)) ? NULL : object_mover, nofail);
+      }
+   };
+
+   template<typename T> struct bitwise_movable< vector<T> > { enum { cFlag = true }; };
+
+   // Hash map
+
+   template <typename T>
+   struct hasher
+   {
+      inline size_t operator() (const T& key) const { return static_cast<size_t>(key); }
+   };
+
+   template <typename T>
+   struct equal_to
+   {
+      inline bool operator()(const T& a, const T& b) const { return a == b; }
+   };
+
+   // Important: The Hasher and Equals objects must be bitwise movable!
+   template<typename Key, typename Value = empty_type, typename Hasher = hasher<Key>, typename Equals = equal_to<Key> >
+   class hash_map
+   {
+      friend class iterator;
+      friend class const_iterator;
+
+      enum state
+      {
+         cStateInvalid = 0,
+         cStateValid = 1
+      };
+
+      enum
+      {
+         cMinHashSize = 4U
+      };
+
+   public:
+      typedef hash_map<Key, Value, Hasher, Equals> hash_map_type;
+      typedef std::pair<Key, Value> value_type;
+      typedef Key                   key_type;
+      typedef Value                 referent_type;
+      typedef Hasher                hasher_type;
+      typedef Equals                equals_type;
+
+      hash_map() :
+         m_hash_shift(32), m_num_valid(0), m_grow_threshold(0)
+      {
+      }
+
+      hash_map(const hash_map& other) :
+         m_values(other.m_values),
+         m_hash_shift(other.m_hash_shift),
+         m_hasher(other.m_hasher),
+         m_equals(other.m_equals),
+         m_num_valid(other.m_num_valid),
+         m_grow_threshold(other.m_grow_threshold)
+      {
+      }
+
+      hash_map& operator= (const hash_map& other)
+      {
+         if (this == &other)
+            return *this;
+
+         clear();
+
+         m_values = other.m_values;
+         m_hash_shift = other.m_hash_shift;
+         m_num_valid = other.m_num_valid;
+         m_grow_threshold = other.m_grow_threshold;
+         m_hasher = other.m_hasher;
+         m_equals = other.m_equals;
+
+         return *this;
+      }
+
+      inline ~hash_map()
+      {
+         clear();
+      }
+
+      const Equals& get_equals() const { return m_equals; }
+      Equals& get_equals() { return m_equals; }
+
+      void set_equals(const Equals& equals) { m_equals = equals; }
+
+      const Hasher& get_hasher() const { return m_hasher; }
+      Hasher& get_hasher() { return m_hasher; }
+
+      void set_hasher(const Hasher& hasher) { m_hasher = hasher; }
+
+      inline void clear()
+      {
+         if (!m_values.empty())
+         {
+            if (BASISU_HAS_DESTRUCTOR(Key) || BASISU_HAS_DESTRUCTOR(Value))
+            {
+               node* p = &get_node(0);
+               node* p_end = p + m_values.size();
+
+               uint32_t num_remaining = m_num_valid;
+               while (p != p_end)
+               {
+                  if (p->state)
+                  {
+                     destruct_value_type(p);
+                     num_remaining--;
+                     if (!num_remaining)
+                        break;
+                  }
+
+                  p++;
+               }
+            }
+
+            m_values.clear_no_destruction();
+
+            m_hash_shift = 32;
+            m_num_valid = 0;
+            m_grow_threshold = 0;
+         }
+      }
+
+      inline void reset()
+      {
+         if (!m_num_valid)
+            return;
+
+         if (BASISU_HAS_DESTRUCTOR(Key) || BASISU_HAS_DESTRUCTOR(Value))
+         {
+            node* p = &get_node(0);
+            node* p_end = p + m_values.size();
+
+            uint32_t num_remaining = m_num_valid;
+            while (p != p_end)
+            {
+               if (p->state)
+               {
+                  destruct_value_type(p);
+                  p->state = cStateInvalid;
+
+                  num_remaining--;
+                  if (!num_remaining)
+                     break;
+               }
+
+               p++;
+            }
+         }
+         else if (sizeof(node) <= 32)
+         {
+            memset(&m_values[0], 0, m_values.size_in_bytes());
+         }
+         else
+         {
+            node* p = &get_node(0);
+            node* p_end = p + m_values.size();
+
+            uint32_t num_remaining = m_num_valid;
+            while (p != p_end)
+            {
+               if (p->state)
+               {
+                  p->state = cStateInvalid;
+
+                  num_remaining--;
+                  if (!num_remaining)
+                     break;
+               }
+
+               p++;
+            }
+         }
+
+         m_num_valid = 0;
+      }
+
+      inline uint32_t size()
+      {
+         return m_num_valid;
+      }
+
+      inline uint32_t get_table_size()
+      {
+         return m_values.size();
+      }
+
+      inline bool empty()
+      {
+         return !m_num_valid;
+      }
+
+      inline void reserve(uint32_t new_capacity)
+      {
+         uint64_t new_hash_size = std::max(1U, new_capacity);
+
+         new_hash_size = new_hash_size * 2ULL;
+
+         if (!helpers::is_power_of_2(new_hash_size))
+            new_hash_size = helpers::next_pow2(new_hash_size);
+
+         new_hash_size = std::max<uint64_t>(cMinHashSize, new_hash_size);
+
+         new_hash_size = std::min<uint64_t>(0x80000000UL, new_hash_size);
+
+         if (new_hash_size > m_values.size())
+            rehash((uint32_t)new_hash_size);
+      }
+
+      class const_iterator;
+
+      class iterator
+      {
+         friend class hash_map<Key, Value, Hasher, Equals>;
+         friend class hash_map<Key, Value, Hasher, Equals>::const_iterator;
+
+      public:
+         inline iterator() : m_pTable(NULL), m_index(0) { }
+         inline iterator(hash_map_type& table, uint32_t index) : m_pTable(&table), m_index(index) { }
+         inline iterator(const iterator& other) : m_pTable(other.m_pTable), m_index(other.m_index) { }
+
+         inline iterator& operator= (const iterator& other)
+         {
+            m_pTable = other.m_pTable;
+            m_index = other.m_index;
+            return *this;
+         }
+
+         // post-increment
+         inline iterator operator++(int)
+         {
+            iterator result(*this);
+            ++*this;
+            return result;
+         }
+
+         // pre-increment
+         inline iterator& operator++()
+         {
+            probe();
+            return *this;
+         }
+
+         inline value_type& operator*() const { return *get_cur(); }
+         inline value_type* operator->() const { return get_cur(); }
+
+         inline bool operator == (const iterator& b) const { return (m_pTable == b.m_pTable) && (m_index == b.m_index); }
+         inline bool operator != (const iterator& b) const { return !(*this == b); }
+         inline bool operator == (const const_iterator& b) const { return (m_pTable == b.m_pTable) && (m_index == b.m_index); }
+         inline bool operator != (const const_iterator& b) const { return !(*this == b); }
+
+      private:
+         hash_map_type* m_pTable;
+         uint32_t m_index;
+
+         inline value_type* get_cur() const
+         {
+            assert(m_pTable && (m_index < m_pTable->m_values.size()));
+            assert(m_pTable->get_node_state(m_index) == cStateValid);
+
+            return &m_pTable->get_node(m_index);
+         }
+
+         inline void probe()
+         {
+            assert(m_pTable);
+            m_index = m_pTable->find_next(m_index);
+         }
+      };
+
+      class const_iterator
+      {
+         friend class hash_map<Key, Value, Hasher, Equals>;
+         friend class hash_map<Key, Value, Hasher, Equals>::iterator;
+
+      public:
+         inline const_iterator() : m_pTable(NULL), m_index(0) { }
+         inline const_iterator(const hash_map_type& table, uint32_t index) : m_pTable(&table), m_index(index) { }
+         inline const_iterator(const iterator& other) : m_pTable(other.m_pTable), m_index(other.m_index) { }
+         inline const_iterator(const const_iterator& other) : m_pTable(other.m_pTable), m_index(other.m_index) { }
+
+         inline const_iterator& operator= (const const_iterator& other)
+         {
+            m_pTable = other.m_pTable;
+            m_index = other.m_index;
+            return *this;
+         }
+
+         inline const_iterator& operator= (const iterator& other)
+         {
+            m_pTable = other.m_pTable;
+            m_index = other.m_index;
+            return *this;
+         }
+
+         // post-increment
+         inline const_iterator operator++(int)
+         {
+            const_iterator result(*this);
+            ++*this;
+            return result;
+         }
+
+         // pre-increment
+         inline const_iterator& operator++()
+         {
+            probe();
+            return *this;
+         }
+
+         inline const value_type& operator*() const { return *get_cur(); }
+         inline const value_type* operator->() const { return get_cur(); }
+
+         inline bool operator == (const const_iterator& b) const { return (m_pTable == b.m_pTable) && (m_index == b.m_index); }
+         inline bool operator != (const const_iterator& b) const { return !(*this == b); }
+         inline bool operator == (const iterator& b) const { return (m_pTable == b.m_pTable) && (m_index == b.m_index); }
+         inline bool operator != (const iterator& b) const { return !(*this == b); }
+
+      private:
+         const hash_map_type* m_pTable;
+         uint32_t m_index;
+
+         inline const value_type* get_cur() const
+         {
+            assert(m_pTable && (m_index < m_pTable->m_values.size()));
+            assert(m_pTable->get_node_state(m_index) == cStateValid);
+
+            return &m_pTable->get_node(m_index);
+         }
+
+         inline void probe()
+         {
+            assert(m_pTable);
+            m_index = m_pTable->find_next(m_index);
+         }
+      };
+
+      inline const_iterator begin() const
+      {
+         if (!m_num_valid)
+            return end();
+
+         return const_iterator(*this, find_next(UINT32_MAX));
+      }
+
+      inline const_iterator end() const
+      {
+         return const_iterator(*this, m_values.size());
+      }
+
+      inline iterator begin()
+      {
+         if (!m_num_valid)
+            return end();
+
+         return iterator(*this, find_next(UINT32_MAX));
+      }
+
+      inline iterator end()
+      {
+         return iterator(*this, m_values.size());
+      }
+
+      // insert_result.first will always point to inserted key/value (or the already existing key/value).
+      // insert_resutt.second will be true if a new key/value was inserted, or false if the key already existed (in which case first will point to the already existing value).
+      typedef std::pair<iterator, bool> insert_result;
+
+      inline insert_result insert(const Key& k, const Value& v = Value())
+      {
+         insert_result result;
+         if (!insert_no_grow(result, k, v))
+         {
+            grow();
+
+            // This must succeed.
+            if (!insert_no_grow(result, k, v))
+            {
+               fprintf(stderr, "insert() failed");
+               abort();
+            }
+         }
+
+         return result;
+      }
+
+      inline insert_result insert(const value_type& v)
+      {
+         return insert(v.first, v.second);
+      }
+
+      inline const_iterator find(const Key& k) const
+      {
+         return const_iterator(*this, find_index(k));
+      }
+
+      inline iterator find(const Key& k)
+      {
+         return iterator(*this, find_index(k));
+      }
+
+      inline bool erase(const Key& k)
+      {
+         uint32_t i = find_index(k);
+
+         if (i >= m_values.size())
+            return false;
+
+         node* pDst = &get_node(i);
+         destruct_value_type(pDst);
+         pDst->state = cStateInvalid;
+
+         m_num_valid--;
+
+         for (; ; )
+         {
+            uint32_t r, j = i;
+
+            node* pSrc = pDst;
+
+            do
+            {
+               if (!i)
+               {
+                  i = m_values.size() - 1;
+                  pSrc = &get_node(i);
+               }
+               else
+               {
+                  i--;
+                  pSrc--;
+               }
+
+               if (!pSrc->state)
+                  return true;
+
+               r = hash_key(pSrc->first);
+
+            } while ((i <= r && r < j) || (r < j && j < i) || (j < i && i <= r));
+
+            move_node(pDst, pSrc);
+
+            pDst = pSrc;
+         }
+      }
+
+      inline void swap(hash_map_type& other)
+      {
+         m_values.swap(other.m_values);
+         std::swap(m_hash_shift, other.m_hash_shift);
+         std::swap(m_num_valid, other.m_num_valid);
+         std::swap(m_grow_threshold, other.m_grow_threshold);
+         std::swap(m_hasher, other.m_hasher);
+         std::swap(m_equals, other.m_equals);
+      }
+
+   private:
+      struct node : public value_type
+      {
+         uint8_t state;
+      };
+
+      static inline void construct_value_type(value_type* pDst, const Key& k, const Value& v)
+      {
+         if (BASISU_IS_BITWISE_COPYABLE(Key))
+            memcpy(&pDst->first, &k, sizeof(Key));
+         else
+            scalar_type<Key>::construct(&pDst->first, k);
+
+         if (BASISU_IS_BITWISE_COPYABLE(Value))
+            memcpy(&pDst->second, &v, sizeof(Value));
+         else
+            scalar_type<Value>::construct(&pDst->second, v);
+      }
+
+      static inline void construct_value_type(value_type* pDst, const value_type* pSrc)
+      {
+         if ((BASISU_IS_BITWISE_COPYABLE(Key)) && (BASISU_IS_BITWISE_COPYABLE(Value)))
+         {
+            memcpy(pDst, pSrc, sizeof(value_type));
+         }
+         else
+         {
+            if (BASISU_IS_BITWISE_COPYABLE(Key))
+               memcpy(&pDst->first, &pSrc->first, sizeof(Key));
+            else
+               scalar_type<Key>::construct(&pDst->first, pSrc->first);
+
+            if (BASISU_IS_BITWISE_COPYABLE(Value))
+               memcpy(&pDst->second, &pSrc->second, sizeof(Value));
+            else
+               scalar_type<Value>::construct(&pDst->second, pSrc->second);
+         }
+      }
+
+      static inline void destruct_value_type(value_type* p)
+      {
+         scalar_type<Key>::destruct(&p->first);
+         scalar_type<Value>::destruct(&p->second);
+      }
+
+      // Moves *pSrc to *pDst efficiently.
+      // pDst should NOT be constructed on entry.
+      static inline void move_node(node* pDst, node* pSrc, bool update_src_state = true)
+      {
+         assert(!pDst->state);
+
+         if (BASISU_IS_BITWISE_COPYABLE_OR_MOVABLE(Key) && BASISU_IS_BITWISE_COPYABLE_OR_MOVABLE(Value))
+         {
+            memcpy(pDst, pSrc, sizeof(node));
+         }
+         else
+         {
+            if (BASISU_IS_BITWISE_COPYABLE_OR_MOVABLE(Key))
+               memcpy(&pDst->first, &pSrc->first, sizeof(Key));
+            else
+            {
+               scalar_type<Key>::construct(&pDst->first, pSrc->first);
+               scalar_type<Key>::destruct(&pSrc->first);
+            }
+
+            if (BASISU_IS_BITWISE_COPYABLE_OR_MOVABLE(Value))
+               memcpy(&pDst->second, &pSrc->second, sizeof(Value));
+            else
+            {
+               scalar_type<Value>::construct(&pDst->second, pSrc->second);
+               scalar_type<Value>::destruct(&pSrc->second);
+            }
+
+            pDst->state = cStateValid;
+         }
+
+         if (update_src_state)
+            pSrc->state = cStateInvalid;
+      }
+
+      struct raw_node
+      {
+         inline raw_node()
+         {
+            node* p = reinterpret_cast<node*>(this);
+            p->state = cStateInvalid;
+         }
+
+         inline ~raw_node()
+         {
+            node* p = reinterpret_cast<node*>(this);
+            if (p->state)
+               hash_map_type::destruct_value_type(p);
+         }
+
+         inline raw_node(const raw_node& other)
+         {
+            node* pDst = reinterpret_cast<node*>(this);
+            const node* pSrc = reinterpret_cast<const node*>(&other);
+
+            if (pSrc->state)
+            {
+               hash_map_type::construct_value_type(pDst, pSrc);
+               pDst->state = cStateValid;
+            }
+            else
+               pDst->state = cStateInvalid;
+         }
+
+         inline raw_node& operator= (const raw_node& rhs)
+         {
+            if (this == &rhs)
+               return *this;
+
+            node* pDst = reinterpret_cast<node*>(this);
+            const node* pSrc = reinterpret_cast<const node*>(&rhs);
+
+            if (pSrc->state)
+            {
+               if (pDst->state)
+               {
+                  pDst->first = pSrc->first;
+                  pDst->second = pSrc->second;
+               }
+               else
+               {
+                  hash_map_type::construct_value_type(pDst, pSrc);
+                  pDst->state = cStateValid;
+               }
+            }
+            else if (pDst->state)
+            {
+               hash_map_type::destruct_value_type(pDst);
+               pDst->state = cStateInvalid;
+            }
+
+            return *this;
+         }
+
+         uint8_t m_bits[sizeof(node)];
+      };
+
+      typedef basisu::vector<raw_node> node_vector;
+
+      node_vector    m_values;
+      uint32_t       m_hash_shift;
+
+      Hasher         m_hasher;
+      Equals         m_equals;
+
+      uint32_t       m_num_valid;
+
+      uint32_t       m_grow_threshold;
+
+      inline uint32_t hash_key(const Key& k) const
+      {
+         assert((1U << (32U - m_hash_shift)) == m_values.size());
+
+         uint32_t hash = static_cast<uint32_t>(m_hasher(k));
+
+         // Fibonacci hashing
+         hash = (2654435769U * hash) >> m_hash_shift;
+
+         assert(hash < m_values.size());
+         return hash;
+      }
+
+      inline const node& get_node(uint32_t index) const
+      {
+         return *reinterpret_cast<const node*>(&m_values[index]);
+      }
+
+      inline node& get_node(uint32_t index)
+      {
+         return *reinterpret_cast<node*>(&m_values[index]);
+      }
+
+      inline state get_node_state(uint32_t index) const
+      {
+         return static_cast<state>(get_node(index).state);
+      }
+
+      inline void set_node_state(uint32_t index, bool valid)
+      {
+         get_node(index).state = valid;
+      }
+
+      inline void grow()
+      {
+         uint64_t n = m_values.size() * 3ULL; // was * 2
+         
+         if (!helpers::is_power_of_2(n))
+            n = helpers::next_pow2(n);
+
+         if (n > 0x80000000UL)
+            n = 0x80000000UL;
+
+         rehash(std::max<uint32_t>(cMinHashSize, (uint32_t)n));
+      }
+
+      inline void rehash(uint32_t new_hash_size)
+      {
+         assert(new_hash_size >= m_num_valid);
+         assert(helpers::is_power_of_2(new_hash_size));
+
+         if ((new_hash_size < m_num_valid) || (new_hash_size == m_values.size()))
+            return;
+
+         hash_map new_map;
+         new_map.m_values.resize(new_hash_size);
+         new_map.m_hash_shift = 32U - helpers::floor_log2i(new_hash_size);
+         assert(new_hash_size == (1U << (32U - new_map.m_hash_shift)));
+         new_map.m_grow_threshold = UINT_MAX;
+
+         node* pNode = reinterpret_cast<node*>(m_values.begin());
+         node* pNode_end = pNode + m_values.size();
+
+         while (pNode != pNode_end)
+         {
+            if (pNode->state)
+            {
+               new_map.move_into(pNode);
+
+               if (new_map.m_num_valid == m_num_valid)
+                  break;
+            }
+
+            pNode++;
+         }
+
+         new_map.m_grow_threshold = (new_hash_size + 1U) >> 1U;
+
+         m_values.clear_no_destruction();
+         m_hash_shift = 32;
+
+         swap(new_map);
+      }
+
+      inline uint32_t find_next(uint32_t index) const
+      {
+         index++;
+
+         if (index >= m_values.size())
+            return index;
+
+         const node* pNode = &get_node(index);
+
+         for (; ; )
+         {
+            if (pNode->state)
+               break;
+
+            if (++index >= m_values.size())
+               break;
+
+            pNode++;
+         }
+
+         return index;
+      }
+
+      inline uint32_t find_index(const Key& k) const
+      {
+         if (m_num_valid)
+         {
+            uint32_t index = hash_key(k);
+            const node* pNode = &get_node(index);
+
+            if (pNode->state)
+            {
+               if (m_equals(pNode->first, k))
+                  return index;
+
+               const uint32_t orig_index = index;
+
+               for (; ; )
+               {
+                  if (!index)
+                  {
+                     index = m_values.size() - 1;
+                     pNode = &get_node(index);
+                  }
+                  else
+                  {
+                     index--;
+                     pNode--;
+                  }
+
+                  if (index == orig_index)
+                     break;
+
+                  if (!pNode->state)
+                     break;
+
+                  if (m_equals(pNode->first, k))
+                     return index;
+               }
+            }
+         }
+
+         return m_values.size();
+      }
+
+      inline bool insert_no_grow(insert_result& result, const Key& k, const Value& v = Value())
+      {
+         if (!m_values.size())
+            return false;
+
+         uint32_t index = hash_key(k);
+         node* pNode = &get_node(index);
+
+         if (pNode->state)
+         {
+            if (m_equals(pNode->first, k))
+            {
+               result.first = iterator(*this, index);
+               result.second = false;
+               return true;
+            }
+
+            const uint32_t orig_index = index;
+
+            for (; ; )
+            {
+               if (!index)
+               {
+                  index = m_values.size() - 1;
+                  pNode = &get_node(index);
+               }
+               else
+               {
+                  index--;
+                  pNode--;
+               }
+
+               if (orig_index == index)
+                  return false;
+
+               if (!pNode->state)
+                  break;
+
+               if (m_equals(pNode->first, k))
+               {
+                  result.first = iterator(*this, index);
+                  result.second = false;
+                  return true;
+               }
+            }
+         }
+
+         if (m_num_valid >= m_grow_threshold)
+            return false;
+
+         construct_value_type(pNode, k, v);
+
+         pNode->state = cStateValid;
+
+         m_num_valid++;
+         assert(m_num_valid <= m_values.size());
+
+         result.first = iterator(*this, index);
+         result.second = true;
+
+         return true;
+      }
+
+      inline void move_into(node* pNode)
+      {
+         uint32_t index = hash_key(pNode->first);
+         node* pDst_node = &get_node(index);
+
+         if (pDst_node->state)
+         {
+            const uint32_t orig_index = index;
+
+            for (; ; )
+            {
+               if (!index)
+               {
+                  index = m_values.size() - 1;
+                  pDst_node = &get_node(index);
+               }
+               else
+               {
+                  index--;
+                  pDst_node--;
+               }
+
+               if (index == orig_index)
+               {
+                  assert(false);
+                  return;
+               }
+
+               if (!pDst_node->state)
+                  break;
+            }
+         }
+
+         move_node(pDst_node, pNode, false);
+
+         m_num_valid++;
+      }
+   };
+
+   template<typename Key, typename Value, typename Hasher, typename Equals>
+   struct bitwise_movable< hash_map<Key, Value, Hasher, Equals> > { enum { cFlag = true }; };
+   
+#if BASISU_HASHMAP_TEST
+   extern void hash_map_test();
+#endif
+      
+} // namespace basisu
+
+namespace std
+{
+   template<typename T>
+   inline void swap(basisu::vector<T>& a, basisu::vector<T>& b)
+   {
+      a.swap(b);
+   }
+
+   template<typename Key, typename Value, typename Hasher, typename Equals>
+   inline void swap(basisu::hash_map<Key, Value, Hasher, Equals>& a, basisu::hash_map<Key, Value, Hasher, Equals>& b)
+   {
+      a.swap(b);
+   }
+
+} // namespace std
\ No newline at end of file
diff --git a/transcoder/basisu_containers_impl.h b/transcoder/basisu_containers_impl.h
new file mode 100644
index 0000000..1a0d7cb
--- /dev/null
+++ b/transcoder/basisu_containers_impl.h
@@ -0,0 +1,311 @@
+// basisu_containers_impl.h
+// Do not include directly
+
+#ifdef _MSC_VER
+#pragma warning (disable:4127) // warning C4127: conditional expression is constant
+#endif
+
+namespace basisu
+{
+   bool elemental_vector::increase_capacity(uint32_t min_new_capacity, bool grow_hint, uint32_t element_size, object_mover pMover, bool nofail)
+   {
+      assert(m_size <= m_capacity);
+
+      if (sizeof(void *) == sizeof(uint64_t))
+         assert(min_new_capacity < (0x400000000ULL / element_size));
+      else
+         assert(min_new_capacity < (0x7FFF0000U / element_size));
+
+      if (m_capacity >= min_new_capacity)
+         return true;
+
+      size_t new_capacity = min_new_capacity;
+      if ((grow_hint) && (!helpers::is_power_of_2((uint64_t)new_capacity)))
+      {
+         new_capacity = (size_t)helpers::next_pow2((uint64_t)new_capacity);
+
+         assert(new_capacity && (new_capacity > m_capacity));
+
+         if (new_capacity < min_new_capacity)
+         {
+            if (nofail)
+               return false;
+            fprintf(stderr, "vector too large\n");
+            abort();
+         }
+      }
+            
+      const size_t desired_size = element_size * new_capacity;
+      size_t actual_size = 0;
+      if (!pMover)
+      {
+         void* new_p = realloc(m_p, desired_size);
+         if (!new_p)
+         {
+            if (nofail)
+               return false;
+
+            char buf[256];
+#ifdef _MSC_VER
+            sprintf_s(buf, sizeof(buf), "vector: realloc() failed allocating %u bytes", (uint32_t)desired_size);
+#else
+            sprintf(buf, "vector: realloc() failed allocating %u bytes", (uint32_t)desired_size);
+#endif
+            fprintf(stderr, "%s", buf);
+            abort();
+         }
+
+#ifdef _MSC_VER
+         actual_size = _msize(new_p);
+//#elif defined(__EMSCRIPTEN__)
+//         actual_size = desired_size;
+#else
+         actual_size = malloc_usable_size(new_p);
+#endif
+         m_p = new_p;
+      }
+      else
+      {
+         void* new_p = malloc(desired_size);
+         if (!new_p)
+         {
+            if (nofail)
+               return false;
+
+            char buf[256];
+#ifdef _MSC_VER
+            sprintf_s(buf, sizeof(buf), "vector: malloc() failed allocating %u bytes", (uint32_t)desired_size);
+#else
+            sprintf(buf, "vector: malloc() failed allocating %u bytes", (uint32_t)desired_size);
+#endif
+            fprintf(stderr, "%s", buf);
+            abort();
+         }
+
+#ifdef _MSC_VER
+         actual_size = _msize(new_p);
+//#elif defined(__EMSCRIPTEN__)
+//         actual_size = desired_size;
+#else
+         actual_size = malloc_usable_size(new_p);
+#endif
+
+         (*pMover)(new_p, m_p, m_size);
+
+         if (m_p)
+            free(m_p);
+         
+         m_p = new_p;
+      }
+
+      if (actual_size > desired_size)
+         m_capacity = static_cast<uint32_t>(actual_size / element_size);
+      else
+         m_capacity = static_cast<uint32_t>(new_capacity);
+
+      return true;
+   }
+
+#if BASISU_HASHMAP_TEST
+
+#define HASHMAP_TEST_VERIFY(c) do { if (!(c)) handle_hashmap_test_verify_failure(__LINE__); } while(0)
+
+   static void handle_hashmap_test_verify_failure(int line)
+   {
+      fprintf(stderr, "HASHMAP_TEST_VERIFY() faild on line %i\n", line);
+      abort();
+   }
+
+   class counted_obj
+   {
+   public:
+      counted_obj(uint32_t v = 0) :
+         m_val(v)
+      {
+         m_count++;
+      }
+
+      counted_obj(const counted_obj& obj) :
+         m_val(obj.m_val)
+      {
+         m_count++;
+      }
+
+      ~counted_obj()
+      {
+         assert(m_count > 0);
+         m_count--;
+      }
+
+      static uint32_t m_count;
+
+      uint32_t m_val;
+
+      operator size_t() const { return m_val; }
+
+      bool operator== (const counted_obj& rhs) const { return m_val == rhs.m_val; }
+      bool operator== (const uint32_t rhs) const { return m_val == rhs; }
+
+   };
+
+   uint32_t counted_obj::m_count;
+
+   static uint32_t urand32()
+   {
+      uint32_t a = rand();
+      uint32_t b = rand() << 15;
+      uint32_t c = rand() << (32 - 15);
+      return a ^ b ^ c;
+   }
+
+   static int irand32(int l, int h)
+   {
+      assert(l < h);
+      if (l >= h)
+         return l;
+
+      uint32_t range = static_cast<uint32_t>(h - l);
+
+      uint32_t rnd = urand32();
+
+      uint32_t rnd_range = static_cast<uint32_t>((((uint64_t)range) * ((uint64_t)rnd)) >> 32U);
+
+      int result = l + rnd_range;
+      assert((result >= l) && (result < h));
+      return result;
+   }
+
+   void hash_map_test()
+   {
+      {
+         basisu::hash_map<uint64_t, uint64_t> k;
+         basisu::hash_map<uint64_t, uint64_t> l;
+         std::swap(k, l);
+
+         k.begin();
+         k.end();
+         k.clear();
+         k.empty();
+         k.erase(0);
+         k.insert(0, 1);
+         k.find(0);
+         k.get_equals();
+         k.get_hasher();
+         k.get_table_size();
+         k.reset();
+         k.reserve(1);
+         k = l;
+         k.set_equals(l.get_equals());
+         k.set_hasher(l.get_hasher());
+         k.get_table_size();
+      }
+
+      uint32_t seed = 0;
+      for (; ; )
+      {
+         seed++;
+
+         typedef basisu::hash_map<counted_obj, counted_obj> my_hash_map;
+         my_hash_map m;
+
+         const uint32_t n = irand32(0, 100000);
+
+         printf("%u\n", n);
+
+         srand(seed); // r1.seed(seed);
+
+         basisu::vector<int> q;
+
+         uint32_t count = 0;
+         for (uint32_t i = 0; i < n; i++)
+         {
+            uint32_t v = urand32() & 0x7FFFFFFF;
+            my_hash_map::insert_result res = m.insert(counted_obj(v), counted_obj(v ^ 0xdeadbeef));
+            if (res.second)
+            {
+               count++;
+               q.push_back(v);
+            }
+         }
+
+         HASHMAP_TEST_VERIFY(m.size() == count);
+
+         srand(seed);
+
+         my_hash_map cm(m);
+         m.clear();
+         m = cm;
+         cm.reset();
+
+         for (uint32_t i = 0; i < n; i++)
+         {
+            uint32_t v = urand32() & 0x7FFFFFFF;
+            my_hash_map::const_iterator it = m.find(counted_obj(v));
+            HASHMAP_TEST_VERIFY(it != m.end());
+            HASHMAP_TEST_VERIFY(it->first == v);
+            HASHMAP_TEST_VERIFY(it->second == (v ^ 0xdeadbeef));
+         }
+
+         for (uint32_t t = 0; t < 2; t++)
+         {
+            const uint32_t nd = irand32(1, q.size() + 1);
+            for (uint32_t i = 0; i < nd; i++)
+            {
+               uint32_t p = irand32(0, q.size());
+
+               int k = q[p];
+               if (k >= 0)
+               {
+                  q[p] = -k - 1;
+
+                  bool s = m.erase(counted_obj(k));
+                  HASHMAP_TEST_VERIFY(s);
+               }
+            }
+
+            typedef basisu::hash_map<uint32_t, empty_type> uint_hash_set;
+            uint_hash_set s;
+
+            for (uint32_t i = 0; i < q.size(); i++)
+            {
+               int v = q[i];
+
+               if (v >= 0)
+               {
+                  my_hash_map::const_iterator it = m.find(counted_obj(v));
+                  HASHMAP_TEST_VERIFY(it != m.end());
+                  HASHMAP_TEST_VERIFY(it->first == (uint32_t)v);
+                  HASHMAP_TEST_VERIFY(it->second == ((uint32_t)v ^ 0xdeadbeef));
+
+                  s.insert(v);
+               }
+               else
+               {
+                  my_hash_map::const_iterator it = m.find(counted_obj(-v - 1));
+                  HASHMAP_TEST_VERIFY(it == m.end());
+               }
+            }
+
+            uint32_t found_count = 0;
+            for (my_hash_map::const_iterator it = m.begin(); it != m.end(); ++it)
+            {
+               HASHMAP_TEST_VERIFY(it->second == ((uint32_t)it->first ^ 0xdeadbeef));
+
+               uint_hash_set::const_iterator fit(s.find((uint32_t)it->first));
+               HASHMAP_TEST_VERIFY(fit != s.end());
+
+               HASHMAP_TEST_VERIFY(fit->first == it->first);
+
+               found_count++;
+            }
+
+            HASHMAP_TEST_VERIFY(found_count == s.size());
+         }
+
+         HASHMAP_TEST_VERIFY(counted_obj::m_count == m.size() * 2);
+      }
+   }
+
+#endif // BASISU_HASHMAP_TEST
+
+} // namespace basisu
