Add basic support for intrinsics. Move sp<> into RScpp.

Change-Id: I74cdee7069a624ded5091d53db3a4b8ce9894033
diff --git a/cpp/Allocation.cpp b/cpp/Allocation.cpp
index a613e45..f05b005 100644
--- a/cpp/Allocation.cpp
+++ b/cpp/Allocation.cpp
@@ -15,7 +15,6 @@
  */
 
 #include "RenderScript.h"
-#include <rs.h>
 
 using namespace android;
 using namespace RSC;
@@ -64,11 +63,14 @@
     mType = t;
     mUsage = usage;
 
-    if (t.get() != NULL) {
+    if (t != NULL) {
         updateCacheInfo(t);
     }
+
 }
 
+
+
 void Allocation::validateIsInt32() {
     RsDataType dt = mType->getElement()->getDataType();
     if ((dt == RS_TYPE_SIGNED_32) || (dt == RS_TYPE_UNSIGNED_32)) {
@@ -178,7 +180,7 @@
     }
 
     RS::dispatch->Allocation1DData(mRS->getContext(), getIDSafe(), off, mSelectedLOD, count, data,
-                       count * mType->getElement()->getSizeBytes());
+                                   count * mType->getElement()->getSizeBytes());
 }
 
 void Allocation::copy1DRangeTo(uint32_t off, size_t count, void *data) {
@@ -192,16 +194,16 @@
     }
 
     RS::dispatch->Allocation1DRead(mRS->getContext(), getIDSafe(), off, mSelectedLOD, count, data,
-                       count * mType->getElement()->getSizeBytes());
+                                   count * mType->getElement()->getSizeBytes());
 }
 
 void Allocation::copy1DRangeFrom(uint32_t off, size_t count, sp<const Allocation> data,
                                  uint32_t dataOff) {
 
     RS::dispatch->AllocationCopy2DRange(mRS->getContext(), getIDSafe(), off, 0,
-                            mSelectedLOD, mSelectedFace,
-                            count, 1, data->getIDSafe(), dataOff, 0,
-                            data->mSelectedLOD, data->mSelectedFace);
+                                        mSelectedLOD, mSelectedFace,
+                                        count, 1, data->getIDSafe(), dataOff, 0,
+                                        data->mSelectedLOD, data->mSelectedFace);
 }
 
 void Allocation::copy1DFrom(const void* data) {
@@ -227,30 +229,30 @@
                                  const void *data) {
     validate2DRange(xoff, yoff, w, h);
     RS::dispatch->Allocation2DData(mRS->getContext(), getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace,
-                       w, h, data, w * h * mType->getElement()->getSizeBytes(), w * mType->getElement()->getSizeBytes());
+                                   w, h, data, w * h * mType->getElement()->getSizeBytes(), w * mType->getElement()->getSizeBytes());
 }
 
 void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
                                  sp<const Allocation> data, uint32_t dataXoff, uint32_t dataYoff) {
     validate2DRange(xoff, yoff, w, h);
     RS::dispatch->AllocationCopy2DRange(mRS->getContext(), getIDSafe(), xoff, yoff,
-                            mSelectedLOD, mSelectedFace,
-                            w, h, data->getIDSafe(), dataXoff, dataYoff,
-                            data->mSelectedLOD, data->mSelectedFace);
+                                        mSelectedLOD, mSelectedFace,
+                                        w, h, data->getIDSafe(), dataXoff, dataYoff,
+                                        data->mSelectedLOD, data->mSelectedFace);
 }
 
 void Allocation::copy2DRangeTo(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
                                void* data) {
     validate2DRange(xoff, yoff, w, h);
     RS::dispatch->Allocation2DRead(mRS->getContext(), getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace,
-                       w, h, data, w * h * mType->getElement()->getSizeBytes(), w * mType->getElement()->getSizeBytes());
+                                   w, h, data, w * h * mType->getElement()->getSizeBytes(), w * mType->getElement()->getSizeBytes());
 }
 
 void Allocation::copy2DStridedFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
                                    const void *data, size_t stride) {
     validate2DRange(xoff, yoff, w, h);
     RS::dispatch->Allocation2DData(mRS->getContext(), getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace,
-                       w, h, data, w * h * mType->getElement()->getSizeBytes(), stride);
+                                   w, h, data, w * h * mType->getElement()->getSizeBytes(), stride);
 }
 
 void Allocation::copy2DStridedFrom(const void* data, size_t stride) {
@@ -261,15 +263,15 @@
                                  void *data, size_t stride) {
     validate2DRange(xoff, yoff, w, h);
     RS::dispatch->Allocation2DRead(mRS->getContext(), getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace,
-                       w, h, data, w * h * mType->getElement()->getSizeBytes(), stride);
+                                   w, h, data, w * h * mType->getElement()->getSizeBytes(), stride);
 }
 
 void Allocation::copy2DStridedTo(void* data, size_t stride) {
     copy2DStridedTo(0, 0, mCurrentDimX, mCurrentDimY, data, stride);
 }
 
-android::sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
-                                                RsAllocationMipmapControl mips, uint32_t usage) {
+sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
+                                    RsAllocationMipmapControl mips, uint32_t usage) {
     void *id = RS::dispatch->AllocationCreateTyped(rs->getContext(), type->getID(), mips, usage, 0);
     if (id == 0) {
         ALOGE("Allocation creation failed.");
@@ -278,24 +280,24 @@
     return new Allocation(id, rs, type, usage);
 }
 
-android::sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
-                                                RsAllocationMipmapControl mips, uint32_t usage,
-                                                void *pointer) {
+sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
+                                    RsAllocationMipmapControl mips, uint32_t usage,
+                                    void *pointer) {
     void *id = RS::dispatch->AllocationCreateTyped(rs->getContext(), type->getID(), mips, usage,
-                                       (uintptr_t)pointer);
+                                                   (uintptr_t)pointer);
     if (id == 0) {
         ALOGE("Allocation creation failed.");
     }
     return new Allocation(id, rs, type, usage);
 }
 
-android::sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
-                                                uint32_t usage) {
+sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
+                                    uint32_t usage) {
     return createTyped(rs, type, RS_ALLOCATION_MIPMAP_NONE, usage);
 }
 
-android::sp<Allocation> Allocation::createSized(sp<RS> rs, sp<const Element> e,
-                                                size_t count, uint32_t usage) {
+sp<Allocation> Allocation::createSized(sp<RS> rs, sp<const Element> e,
+                                    size_t count, uint32_t usage) {
     Type::Builder b(rs, e);
     b.setX(count);
     sp<const Type> t = b.create();
@@ -303,8 +305,8 @@
     return createTyped(rs, t, usage);
 }
 
-android::sp<Allocation> Allocation::createSized2D(sp<RS> rs, sp<const Element> e,
-                                                  size_t x, size_t y, uint32_t usage) {
+sp<Allocation> Allocation::createSized2D(sp<RS> rs, sp<const Element> e,
+                                      size_t x, size_t y, uint32_t usage) {
     Type::Builder b(rs, e);
     b.setX(x);
     b.setY(y);
diff --git a/cpp/Android.mk b/cpp/Android.mk
index 3613eae..d266d14 100644
--- a/cpp/Android.mk
+++ b/cpp/Android.mk
@@ -1,3 +1,14 @@
+rs_cpp_SRC_FILES := \
+	RenderScript.cpp \
+	BaseObj.cpp \
+	Element.cpp \
+	Type.cpp \
+	Allocation.cpp \
+	Script.cpp \
+	ScriptC.cpp \
+	ScriptIntrinsics.cpp \
+	Sampler.cpp
+
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
@@ -11,38 +22,50 @@
 endif
 local_cflags_for_rs_cpp += -DRS_VERSION=$(RS_VERSION)
 
-LOCAL_CFLAGS += $(local_cflags_for_rs_cpp)
+LOCAL_SRC_FILES := $(rs_cpp_SRC_FILES)
 
-LOCAL_SRC_FILES:= \
-	RenderScript.cpp \
-	BaseObj.cpp \
-	Element.cpp \
-	Type.cpp \
-	Allocation.cpp \
-	Script.cpp \
-	ScriptC.cpp \
-	ScriptIntrinsics.cpp \
-	Sampler.cpp
+LOCAL_CFLAGS += $(local_cflags_for_rs_cpp)
 
 LOCAL_SHARED_LIBRARIES := \
 	libz \
 	libcutils \
 	libutils \
 	liblog \
-	libdl
+	libdl \
+	libstlport
 
 LOCAL_MODULE:= libRScpp
 
 LOCAL_MODULE_TAGS := optional
 
-intermediates := $(call intermediates-dir-for,STATIC_LIBRARIES,libRS,TARGET,)
-librs_generated_headers := \
-    $(intermediates)/rsgApiStructs.h \
-    $(intermediates)/rsgApiFuncDecl.h
-LOCAL_GENERATED_SOURCES := $(librs_generated_headers)
-
 LOCAL_C_INCLUDES += frameworks/rs
+LOCAL_C_INCLUDES += external/stlport/stlport bionic/ bionic/libstdc++/include
 LOCAL_C_INCLUDES += $(intermediates)
 
-
 include $(BUILD_SHARED_LIBRARY)
+
+
+include $(CLEAR_VARS)
+
+LOCAL_CFLAGS += $(local_cflags_for_rs_cpp)
+
+LOCAL_SRC_FILES := $(rs_cpp_SRC_FILES)
+
+LOCAL_STATIC_LIBRARIES := \
+	libz \
+	libcutils \
+	libutils \
+	liblog \
+	libstlport_static
+
+LOCAL_SHARED_LIBRARIES := libdl
+
+LOCAL_MODULE:= libRScpp_static
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_C_INCLUDES += frameworks/rs
+LOCAL_C_INCLUDES += external/stlport/stlport bionic/ bionic/libstdc++/include
+LOCAL_C_INCLUDES += $(intermediates)
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/cpp/BaseObj.cpp b/cpp/BaseObj.cpp
index 814e552..efcb83a 100644
--- a/cpp/BaseObj.cpp
+++ b/cpp/BaseObj.cpp
@@ -15,7 +15,6 @@
  */
 
 #include "RenderScript.h"
-#include <rs.h>
 
 using namespace android;
 using namespace RSC;
@@ -28,7 +27,7 @@
 }
 
 void * BaseObj::getObjID(sp<const BaseObj> o) {
-    return o.get() == NULL ? NULL : o->getID();
+    return o == NULL ? NULL : o->getID();
 }
 
 
@@ -55,9 +54,9 @@
     mName = name;
 }
 
-bool BaseObj::equals(const BaseObj *obj) {
+bool BaseObj::equals(sp<const BaseObj> obj) {
     // Early-out check to see if both BaseObjs are actually the same
-    if (this == obj)
+    if (this == obj.get())
         return true;
     return mID == obj->mID;
 }
diff --git a/cpp/Element.cpp b/cpp/Element.cpp
index 1289c6e..d4b2c66 100644
--- a/cpp/Element.cpp
+++ b/cpp/Element.cpp
@@ -18,12 +18,11 @@
 #include <string.h>
 
 #include "RenderScript.h"
-#include <rs.h>
 
 using namespace android;
 using namespace RSC;
 
-sp<const Element> Element::getSubElement(uint32_t index) {
+android::RSC::sp<const Element> Element::getSubElement(uint32_t index) {
     if (!mVisibleElementMap.size()) {
         mRS->throwError("Element contains no sub-elements");
     }
@@ -64,7 +63,7 @@
 }
 
 
-#define CREATE_USER(N, T) sp<const Element> Element::N(sp<RS> rs) { \
+#define CREATE_USER(N, T) android::RSC::sp<const Element> Element::N(android::RSC::sp<RS> rs) { \
     if (rs->mElements.N == NULL) {                                  \
         rs->mElements.N = (createUser(rs, RS_TYPE_##T)).get();      \
     }                                                               \
@@ -96,7 +95,7 @@
 CREATE_USER(MATRIX_3X3, MATRIX_3X3);
 CREATE_USER(MATRIX_2X2, MATRIX_2X2);
 
-#define CREATE_PIXEL(N, T, K) sp<const Element> Element::N(sp<RS> rs) { \
+#define CREATE_PIXEL(N, T, K) android::RSC::sp<const Element> Element::N(android::RSC::sp<RS> rs) { \
     return createPixel(rs, RS_TYPE_##T, RS_KIND_##K); \
 }
 CREATE_PIXEL(A_8, UNSIGNED_8, PIXEL_A);
@@ -105,13 +104,13 @@
 CREATE_PIXEL(RGBA_4444, UNSIGNED_4_4_4_4, PIXEL_RGBA);
 CREATE_PIXEL(RGBA_8888, UNSIGNED_8, PIXEL_RGBA);
 
-#define CREATE_VECTOR(N, T) sp<const Element> Element::N##_2(sp<RS> rs) { \
+#define CREATE_VECTOR(N, T) android::RSC::sp<const Element> Element::N##_2(android::RSC::sp<RS> rs) { \
     return createVector(rs, RS_TYPE_##T, 2); \
 } \
-sp<const Element> Element::N##_3(sp<RS> rs) { \
+android::RSC::sp<const Element> Element::N##_3(android::RSC::sp<RS> rs) { \
     return createVector(rs, RS_TYPE_##T, 3); \
 } \
-sp<const Element> Element::N##_4(sp<RS> rs) { \
+android::RSC::sp<const Element> Element::N##_4(android::RSC::sp<RS> rs) { \
     return createVector(rs, RS_TYPE_##T, 4); \
 }
 CREATE_VECTOR(U8, UNSIGNED_8);
@@ -144,15 +143,15 @@
     // Make a map that points us at non-padding elements
     for (size_t ct = 0; ct < fieldCount; ct ++) {
         if (mElementNames[ct].string()[0] != '#') {
-            mVisibleElementMap.push((uint32_t)ct);
+            mVisibleElementMap.push_back((uint32_t)ct);
         }
     }
 }
 
-Element::Element(void *id, sp<RS> rs,
-                 android::Vector<sp<Element> > &elements,
-                 android::Vector<android::String8> &elementNames,
-                 android::Vector<uint32_t> &arraySizes) : BaseObj(id, rs) {
+Element::Element(void *id, android::RSC::sp<RS> rs,
+                 std::vector<android::RSC::sp<Element> > &elements,
+                 std::vector<android::String8> &elementNames,
+                 std::vector<uint32_t> &arraySizes) : BaseObj(id, rs) {
     mSizeBytes = 0;
     mVectorSize = 1;
     mElements = elements;
@@ -163,7 +162,7 @@
     mKind = RS_KIND_USER;
 
     for (size_t ct = 0; ct < mElements.size(); ct++ ) {
-        mOffsetInBytes.push(mSizeBytes);
+        mOffsetInBytes.push_back(mSizeBytes);
         mSizeBytes += mElements[ct]->mSizeBytes * mArraySizes[ct];
     }
     updateVisibleSubElements();
@@ -223,7 +222,7 @@
     return 0;
 }
 
-Element::Element(void *id, sp<RS> rs,
+Element::Element(void *id, android::RSC::sp<RS> rs,
                  RsDataType dt, RsDataKind dk, bool norm, uint32_t size) :
     BaseObj(id, rs)
 {
@@ -253,12 +252,12 @@
     updateVisibleSubElements();
 }
 
-sp<const Element> Element::createUser(sp<RS> rs, RsDataType dt) {
+android::RSC::sp<const Element> Element::createUser(android::RSC::sp<RS> rs, RsDataType dt) {
     void * id = RS::dispatch->ElementCreate(rs->getContext(), dt, RS_KIND_USER, false, 1);
     return new Element(id, rs, dt, RS_KIND_USER, false, 1);
 }
 
-sp<const Element> Element::createVector(sp<RS> rs, RsDataType dt, uint32_t size) {
+android::RSC::sp<const Element> Element::createVector(android::RSC::sp<RS> rs, RsDataType dt, uint32_t size) {
     if (size < 2 || size > 4) {
         rs->throwError("Vector size out of range 2-4.");
     }
@@ -266,7 +265,7 @@
     return new Element(id, rs, dt, RS_KIND_USER, false, size);
 }
 
-sp<const Element> Element::createPixel(sp<RS> rs, RsDataType dt, RsDataKind dk) {
+android::RSC::sp<const Element> Element::createPixel(android::RSC::sp<RS> rs, RsDataType dt, RsDataKind dk) {
     if (!(dk == RS_KIND_PIXEL_L ||
           dk == RS_KIND_PIXEL_A ||
           dk == RS_KIND_PIXEL_LA ||
@@ -317,7 +316,7 @@
     return new Element(id, rs, dt, dk, true, size);
 }
 
-bool Element::isCompatible(sp<const Element>e) {
+bool Element::isCompatible(android::RSC::sp<const Element>e) {
     // Try strict BaseObj equality to start with.
     if (this == e.get()) {
         return true;
@@ -333,12 +332,12 @@
             (mVectorSize == e->mVectorSize));
 }
 
-Element::Builder::Builder(sp<RS> rs) {
+Element::Builder::Builder(android::RSC::sp<RS> rs) {
     mRS = rs;
     mSkipPadding = false;
 }
 
-void Element::Builder::add(sp</*const*/ Element>e, android::String8 &name, uint32_t arraySize) {
+void Element::Builder::add(android::RSC::sp</*const*/ Element>e, android::String8 &name, uint32_t arraySize) {
     // Skip padding fields after a vector 3 type.
     if (mSkipPadding) {
         const char *s1 = "#padding_";
@@ -358,12 +357,12 @@
         mSkipPadding = false;
     }
 
-    mElements.add(e);
-    mElementNames.add(name);
-    mArraySizes.add(arraySize);
+    mElements.push_back(e);
+    mElementNames.push_back(name);
+    mArraySizes.push_back(arraySize);
 }
 
-sp<const Element> Element::Builder::create() {
+android::RSC::sp<const Element> Element::Builder::create() {
     size_t fieldCount = mElements.size();
     const char ** nameArray = (const char **)calloc(fieldCount, sizeof(char *));
     const Element ** elementArray = (const Element **)calloc(fieldCount, sizeof(Element *));
@@ -378,7 +377,7 @@
     void *id = RS::dispatch->ElementCreate2(mRS->getContext(),
                                 (RsElement *)elementArray, fieldCount,
                                 nameArray, fieldCount * sizeof(size_t),  sizeArray,
-                                (const uint32_t *)mArraySizes.array(), fieldCount);
+                                (const uint32_t *)&mArraySizes[0], fieldCount);
 
 
     free(nameArray);
diff --git a/cpp/RenderScript.cpp b/cpp/RenderScript.cpp
index c7204e3..18e7117 100644
--- a/cpp/RenderScript.cpp
+++ b/cpp/RenderScript.cpp
@@ -19,7 +19,7 @@
 #include <pthread.h>
 
 #include "RenderScript.h"
-#include "rs.h"
+#include "rsCppStructs.h"
 
 #include <dlfcn.h>
 
diff --git a/cpp/RenderScript.h b/cpp/RenderScript.h
index 9a7a565..8ed8d0e 100644
--- a/cpp/RenderScript.h
+++ b/cpp/RenderScript.h
@@ -17,7 +17,6 @@
 #ifndef ANDROID_RENDERSCRIPT_H
 #define ANDROID_RENDERSCRIPT_H
 
-#include "rsDefines.h"
 #include "rsCppStructs.h"
 
 #ifdef RS_SERVER
diff --git a/cpp/Sampler.cpp b/cpp/Sampler.cpp
index fa6b2fd..a1f4669 100644
--- a/cpp/Sampler.cpp
+++ b/cpp/Sampler.cpp
@@ -15,7 +15,6 @@
  */
 
 #include "RenderScript.h"
-#include <rs.h>
 
 using namespace android;
 using namespace RSC;
@@ -58,7 +57,7 @@
 
 #define CREATE_SAMPLER(N, MIN, MAG, WRAPS, WRAPT) sp<const Sampler> Sampler::N(sp<RS> rs) { \
         if (rs->mSamplers.N == NULL) {                                  \
-            rs->mSamplers.N = (create(rs, MIN, MAG, WRAPS, WRAPT, 0.f)).get(); \
+            rs->mSamplers.N = (create(rs, MIN, MAG, WRAPS, WRAPT, 0.f)); \
         }                                                               \
         return rs->mSamplers.N;                                         \
     }
diff --git a/cpp/Script.cpp b/cpp/Script.cpp
index 70754d0..9bc55ff 100644
--- a/cpp/Script.cpp
+++ b/cpp/Script.cpp
@@ -17,7 +17,6 @@
 #include <malloc.h>
 
 #include "RenderScript.h"
-#include <rs.h>
 
 using namespace android;
 using namespace RSC;
diff --git a/cpp/ScriptC.cpp b/cpp/ScriptC.cpp
index 70d7ba5..0d653bd 100644
--- a/cpp/ScriptC.cpp
+++ b/cpp/ScriptC.cpp
@@ -15,7 +15,6 @@
  */
 
 #include "RenderScript.h"
-#include <rs.h>
 
 using namespace android;
 using namespace RSC;
diff --git a/cpp/ScriptIntrinsics.cpp b/cpp/ScriptIntrinsics.cpp
index 44c5bb6..76328c4 100644
--- a/cpp/ScriptIntrinsics.cpp
+++ b/cpp/ScriptIntrinsics.cpp
@@ -17,8 +17,6 @@
 #include <malloc.h>
 
 #include "RenderScript.h"
-#include <rs.h>
-#include "rsDefines.h"
 
 using namespace android;
 using namespace RSC;
@@ -28,9 +26,19 @@
     mID = RS::dispatch->ScriptIntrinsicCreate(rs->getContext(), id, e->getID());
 }
 
+ScriptIntrinsic3DLUT::ScriptIntrinsic3DLUT(sp<RS> rs, sp<const Element> e)
+    : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_3DLUT, e) {
+
+}
+void ScriptIntrinsic3DLUT::forEach(sp<Allocation> ain, sp<Allocation> aout) {
+    Script::forEach(0, ain, aout, NULL, 0);
+}
+void ScriptIntrinsic3DLUT::setLUT(sp<Allocation> lut) {
+    Script::setVar(0, lut);
+}
+
 ScriptIntrinsicBlend::ScriptIntrinsicBlend(sp<RS> rs, sp<const Element> e)
     : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLEND, e) {
-
 }
 
 void ScriptIntrinsicBlend::blendClear(sp<Allocation> in, sp<Allocation> out) {
@@ -95,6 +103,9 @@
     Script::forEach(35, in, out, NULL, 0);
 }
 
+
+
+
 ScriptIntrinsicBlur::ScriptIntrinsicBlur(sp<RS> rs, sp<const Element> e)
     : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLUR, e) {
 
@@ -108,3 +119,90 @@
 void ScriptIntrinsicBlur::setRadius(float radius) {
     Script::setVar(0, &radius, sizeof(float));
 }
+
+
+
+ScriptIntrinsicColorMatrix::ScriptIntrinsicColorMatrix(sp<RS> rs, sp<const Element> e)
+    : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_COLOR_MATRIX, e) {
+
+}
+
+void ScriptIntrinsicColorMatrix::forEach(sp<Allocation> in, sp<Allocation> out) {
+    Script::forEach(0, in, out, NULL, 0);
+}
+
+
+void ScriptIntrinsicColorMatrix::setColorMatrix3(float* m) {
+    Script::setVar(0, (void*)m, sizeof(float) * 9);
+}
+
+
+void ScriptIntrinsicColorMatrix::setColorMatrix4(float* m) {
+    Script::setVar(0, (void*)m, sizeof(float) * 16);
+}
+
+
+void ScriptIntrinsicColorMatrix::setGreyscale() {
+    float matrix[] = {0.299f, 0.587f,  0.114f, 0.299f, 0.587f, 0.114f, 0.299f, 0.587f, 0.114f};
+    setColorMatrix3(matrix);
+}
+
+
+void ScriptIntrinsicColorMatrix::setRGBtoYUV() {
+    float matrix[] = {0.299f,0.587f,0.114f,-0.14713f,-0.28886f,0.436f,0.615f,-0.51499f,-0.10001f};
+    setColorMatrix3(matrix);
+}
+
+
+void ScriptIntrinsicColorMatrix::setYUVtoRGB() {
+    float matrix[] = {1.f,0.f,1.13983f,1.f,-0.39465f,-0.5806f,1.f,2.03211f,0.f};
+    setColorMatrix3(matrix);
+}
+
+ScriptIntrinsicConvolve3x3::ScriptIntrinsicConvolve3x3(sp<RS> rs, sp<const Element> e)
+    : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_CONVOLVE_3x3, e) {
+
+}
+
+void ScriptIntrinsicConvolve3x3::setInput(sp<Allocation> in) {
+    Script::setVar(1, in);
+}
+
+void ScriptIntrinsicConvolve3x3::forEach(sp<Allocation> out) {
+    Script::forEach(0, NULL, out, NULL, 0);
+}
+
+void ScriptIntrinsicConvolve3x3::setCoefficients(float* v) {
+    Script::setVar(0, (void*)v, sizeof(float) * 9);
+}
+
+ScriptIntrinsicConvolve5x5::ScriptIntrinsicConvolve5x5(sp<RS> rs, sp<const Element> e)
+    : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_CONVOLVE_5x5, e) {
+
+}
+
+void ScriptIntrinsicConvolve5x5::setInput(sp<Allocation> in) {
+    Script::setVar(1, in);
+}
+
+void ScriptIntrinsicConvolve5x5::forEach(sp<Allocation> out) {
+    Script::forEach(0, NULL, out, NULL, 0);
+}
+
+void ScriptIntrinsicConvolve5x5::setCoefficients(float* v) {
+    Script::setVar(0, (void*)v, sizeof(float) * 25);
+}
+
+/*ScriptIntrinsicLUT::ScriptIntrinsicLUT(sp<RS> rs, sp<const Element> e)
+    : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_LUT, e) {
+
+}
+
+void ScriptIntrinsicLUT::forEach(sp<Allocation> ain, sp<Allocation> aout) {
+
+}
+
+void ScriptIntrinsicLUT::setLUT(sp<Allocation> lut) {
+
+}*/
+
diff --git a/cpp/Type.cpp b/cpp/Type.cpp
index a8acde4..192dc68 100644
--- a/cpp/Type.cpp
+++ b/cpp/Type.cpp
@@ -17,7 +17,6 @@
 #include <malloc.h>
 #include <string.h>
 
-#include <rs.h>
 #include "RenderScript.h"
 
 using namespace android;
diff --git a/cpp/rsCppStructs.h b/cpp/rsCppStructs.h
index b948c91..b85499c 100644
--- a/cpp/rsCppStructs.h
+++ b/cpp/rsCppStructs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 The Android Open Source Project
+ * Copyright (C) 2013 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,15 +17,13 @@
 #ifndef ANDROID_RSCPPSTRUCTS_H
 #define ANDROID_RSCPPSTRUCTS_H
 
+#include "rsDefines.h"
 #include "rsCppUtils.h"
-#ifndef RS_SERVER
-#include "utils/RefBase.h"
-#else
-#include "RefBase.h"
-#endif
-
+#include "util/RefBase.h"
 #include "rsDispatch.h"
 
+#include <vector>
+
 // Every row in an RS allocation is guaranteed to be aligned by this amount
 // Every row in a user-backed allocation must be aligned by this amount
 #define RS_CPU_ALLOCATION_ALIGNMENT 16
@@ -45,7 +43,7 @@
 class ScriptC;
 class Sampler;
 
-class RS : public android::LightRefBase<RS> {
+ class RS : public android::RSC::LightRefBase<RS> {
 
  public:
     RS();
@@ -89,97 +87,103 @@
     bool mInit;
 
     struct {
-        const Element *U8;
-        const Element *I8;
-        const Element *U16;
-        const Element *I16;
-        const Element *U32;
-        const Element *I32;
-        const Element *U64;
-        const Element *I64;
-        const Element *F32;
-        const Element *F64;
-        const Element *BOOLEAN;
+        sp<const Element> U8;
+        sp<const Element> I8;
+        sp<const Element> U16;
+        sp<const Element> I16;
+        sp<const Element> U32;
+        sp<const Element> I32;
+        sp<const Element> U64;
+        sp<const Element> I64;
+        sp<const Element> F32;
+        sp<const Element> F64;
+        sp<const Element> BOOLEAN;
 
-        const Element *ELEMENT;
-        const Element *TYPE;
-        const Element *ALLOCATION;
-        const Element *SAMPLER;
-        const Element *SCRIPT;
-        const Element *MESH;
-        const Element *PROGRAM_FRAGMENT;
-        const Element *PROGRAM_VERTEX;
-        const Element *PROGRAM_RASTER;
-        const Element *PROGRAM_STORE;
+        sp<const Element> ELEMENT;
+        sp<const Element> TYPE;
+        sp<const Element> ALLOCATION;
+        sp<const Element> SAMPLER;
+        sp<const Element> SCRIPT;
+        sp<const Element> MESH;
+        sp<const Element> PROGRAM_FRAGMENT;
+        sp<const Element> PROGRAM_VERTEX;
+        sp<const Element> PROGRAM_RASTER;
+        sp<const Element> PROGRAM_STORE;
 
-        const Element *A_8;
-        const Element *RGB_565;
-        const Element *RGB_888;
-        const Element *RGBA_5551;
-        const Element *RGBA_4444;
-        const Element *RGBA_8888;
+        sp<const Element> A_8;
+        sp<const Element> RGB_565;
+        sp<const Element> RGB_888;
+        sp<const Element> RGBA_5551;
+        sp<const Element> RGBA_4444;
+        sp<const Element> RGBA_8888;
 
-        const Element *FLOAT_2;
-        const Element *FLOAT_3;
-        const Element *FLOAT_4;
+        sp<const Element> FLOAT_2;
+        sp<const Element> FLOAT_3;
+        sp<const Element> FLOAT_4;
 
-        const Element *DOUBLE_2;
-        const Element *DOUBLE_3;
-        const Element *DOUBLE_4;
+        sp<const Element> DOUBLE_2;
+        sp<const Element> DOUBLE_3;
+        sp<const Element> DOUBLE_4;
 
-        const Element *UCHAR_2;
-        const Element *UCHAR_3;
-        const Element *UCHAR_4;
+        sp<const Element> UCHAR_2;
+        sp<const Element> UCHAR_3;
+        sp<const Element> UCHAR_4;
 
-        const Element *CHAR_2;
-        const Element *CHAR_3;
-        const Element *CHAR_4;
+        sp<const Element> CHAR_2;
+        sp<const Element> CHAR_3;
+        sp<const Element> CHAR_4;
 
-        const Element *USHORT_2;
-        const Element *USHORT_3;
-        const Element *USHORT_4;
+        sp<const Element> USHORT_2;
+        sp<const Element> USHORT_3;
+        sp<const Element> USHORT_4;
 
-        const Element *SHORT_2;
-        const Element *SHORT_3;
-        const Element *SHORT_4;
+        sp<const Element> SHORT_2;
+        sp<const Element> SHORT_3;
+        sp<const Element> SHORT_4;
 
-        const Element *UINT_2;
-        const Element *UINT_3;
-        const Element *UINT_4;
+        sp<const Element> UINT_2;
+        sp<const Element> UINT_3;
+        sp<const Element> UINT_4;
 
-        const Element *INT_2;
-        const Element *INT_3;
-        const Element *INT_4;
+        sp<const Element> INT_2;
+        sp<const Element> INT_3;
+        sp<const Element> INT_4;
 
-        const Element *ULONG_2;
-        const Element *ULONG_3;
-        const Element *ULONG_4;
+        sp<const Element> ULONG_2;
+        sp<const Element> ULONG_3;
+        sp<const Element> ULONG_4;
 
-        const Element *LONG_2;
-        const Element *LONG_3;
-        const Element *LONG_4;
+        sp<const Element> LONG_2;
+        sp<const Element> LONG_3;
+        sp<const Element> LONG_4;
 
-        const Element *MATRIX_4X4;
-        const Element *MATRIX_3X3;
-        const Element *MATRIX_2X2;
+        sp<const Element> MATRIX_4X4;
+        sp<const Element> MATRIX_3X3;
+        sp<const Element> MATRIX_2X2;
     } mElements;
 
     struct {
-        const Sampler* CLAMP_NEAREST;
-        const Sampler* CLAMP_LINEAR;
-        const Sampler* CLAMP_LINEAR_MIP_LINEAR;
-        const Sampler* WRAP_NEAREST;
-        const Sampler* WRAP_LINEAR;
-        const Sampler* WRAP_LINEAR_MIP_LINEAR;
-        const Sampler* MIRRORED_REPEAT_NEAREST;
-        const Sampler* MIRRORED_REPEAT_LINEAR;
-        const Sampler* MIRRORED_REPEAT_LINEAR_MIP_LINEAR;
+        sp<const Sampler> CLAMP_NEAREST;
+        sp<const Sampler> CLAMP_LINEAR;
+        sp<const Sampler> CLAMP_LINEAR_MIP_LINEAR;
+        sp<const Sampler> WRAP_NEAREST;
+        sp<const Sampler> WRAP_LINEAR;
+        sp<const Sampler> WRAP_LINEAR_MIP_LINEAR;
+        sp<const Sampler> MIRRORED_REPEAT_NEAREST;
+        sp<const Sampler> MIRRORED_REPEAT_LINEAR;
+        sp<const Sampler> MIRRORED_REPEAT_LINEAR_MIP_LINEAR;
     } mSamplers;
     friend class Sampler;
     friend class Element;
 };
 
-class BaseObj : public android::LightRefBase<BaseObj> {
+class BaseObj : public android::RSC::LightRefBase<BaseObj> {
+public:
+    void * getID() const;
+    virtual ~BaseObj();
+    virtual void updateFromNative();
+    virtual bool equals(sp<const BaseObj> obj);
+
 protected:
     void *mID;
     sp<RS> mRS;
@@ -190,20 +194,14 @@
 
     static void * getObjID(sp<const BaseObj> o);
 
-public:
-
-    void * getID() const;
-    virtual ~BaseObj();
-    virtual void updateFromNative();
-    virtual bool equals(const BaseObj *obj);
 };
 
 
 class Allocation : public BaseObj {
 protected:
-    android::sp<const Type> mType;
+    sp<const Type> mType;
     uint32_t mUsage;
-    android::sp<Allocation> mAdaptedAllocation;
+    sp<Allocation> mAdaptedAllocation;
 
     bool mConstrainedLOD;
     bool mConstrainedFace;
@@ -237,7 +235,7 @@
     void validate2DRange(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h);
 
 public:
-    android::sp<const Type> getType() {
+    sp<const Type> getType() {
         return mType;
     }
 
@@ -377,43 +375,44 @@
     static sp<const Element> MATRIX_3X3(sp<RS> rs);
     static sp<const Element> MATRIX_2X2(sp<RS> rs);
 
-    Element(void *id, sp<RS> rs,
-            android::Vector<sp<Element> > &elements,
-            android::Vector<android::String8> &elementNames,
-            android::Vector<uint32_t> &arraySizes);
-    Element(void *id, sp<RS> rs, RsDataType dt, RsDataKind dk, bool norm, uint32_t size);
-    Element(sp<RS> rs);
-    virtual ~Element();
-
     void updateFromNative();
     static sp<const Element> createUser(sp<RS> rs, RsDataType dt);
     static sp<const Element> createVector(sp<RS> rs, RsDataType dt, uint32_t size);
     static sp<const Element> createPixel(sp<RS> rs, RsDataType dt, RsDataKind dk);
     bool isCompatible(sp<const Element>e);
 
+    Element(void *id, sp<RS> rs,
+            std::vector<sp<Element> > &elements,
+            std::vector<android::String8> &elementNames,
+            std::vector<uint32_t> &arraySizes);
+    Element(void *id, sp<RS> rs, RsDataType dt, RsDataKind dk, bool norm, uint32_t size);
+    Element(sp<RS> rs);
+    virtual ~Element();
+
+ protected:
     class Builder {
     private:
         sp<RS> mRS;
-        android::Vector<sp<Element> > mElements;
-        android::Vector<android::String8> mElementNames;
-        android::Vector<uint32_t> mArraySizes;
+        std::vector<sp<Element> > mElements;
+        std::vector<android::String8> mElementNames;
+        std::vector<uint32_t> mArraySizes;
         bool mSkipPadding;
 
     public:
         Builder(sp<RS> rs);
         ~Builder();
-        void add(sp<Element>, android::String8 &name, uint32_t arraySize = 1);
+        void add(sp<Element> e, android::String8 &name, uint32_t arraySize = 1);
         sp<const Element> create();
     };
 
 private:
     void updateVisibleSubElements();
 
-    android::Vector<sp</*const*/ Element> > mElements;
-    android::Vector<android::String8> mElementNames;
-    android::Vector<uint32_t> mArraySizes;
-    android::Vector<uint32_t> mVisibleElementMap;
-    android::Vector<uint32_t> mOffsetInBytes;
+    std::vector<sp<Element> > mElements;
+    std::vector<android::String8> mElementNames;
+    std::vector<uint32_t> mArraySizes;
+    std::vector<uint32_t> mVisibleElementMap;
+    std::vector<uint32_t> mOffsetInBytes;
 
     RsDataType mType;
     RsDataKind mKind;
@@ -430,10 +429,9 @@
 
 public:
     FieldPacker(size_t len)
-        : mPos(0),
-          mLen(len) {
-        mData = new unsigned char[len];
-    }
+        : mPos(0), mLen(len) {
+            mData = new unsigned char[len];
+        }
 
     virtual ~FieldPacker() {
         delete [] mData;
@@ -480,7 +478,7 @@
     }
 
     template <typename T>
-    void add(T t) {
+        void add(T t) {
         align(sizeof(t));
         if (mPos + sizeof(t) <= mLen) {
             memcpy(&mData[mPos], &t, sizeof(t));
@@ -489,26 +487,26 @@
     }
 
     /*
-    void add(rs_matrix4x4 m) {
-        for (size_t i = 0; i < 16; i++) {
-            add(m.m[i]);
-        }
-    }
+      void add(rs_matrix4x4 m) {
+      for (size_t i = 0; i < 16; i++) {
+      add(m.m[i]);
+      }
+      }
 
-    void add(rs_matrix3x3 m) {
-        for (size_t i = 0; i < 9; i++) {
-            add(m.m[i]);
-        }
-    }
+      void add(rs_matrix3x3 m) {
+      for (size_t i = 0; i < 9; i++) {
+      add(m.m[i]);
+      }
+      }
 
-    void add(rs_matrix2x2 m) {
-        for (size_t i = 0; i < 4; i++) {
-            add(m.m[i]);
-        }
-    }
+      void add(rs_matrix2x2 m) {
+      for (size_t i = 0; i < 4; i++) {
+      add(m.m[i]);
+      }
+      }
     */
 
-    void add(BaseObj* obj) {
+    void add(sp<BaseObj> obj) {
         if (obj != NULL) {
             add((uint32_t) (uintptr_t) obj->getID());
         } else {
@@ -517,6 +515,7 @@
     }
 };
 
+
 class Type : public BaseObj {
 protected:
     friend class Allocation;
@@ -663,9 +662,16 @@
     ScriptIntrinsic(sp<RS> rs, int id, sp<const Element> e);
 };
 
+class ScriptIntrinsic3DLUT : public ScriptIntrinsic {
+ public:
+    ScriptIntrinsic3DLUT(sp<RS> rs, sp<const Element> e);
+    void forEach(sp<Allocation> ain, sp<Allocation> aout);
+    void setLUT(sp<Allocation> lut);
+};
+
 class ScriptIntrinsicBlend : public ScriptIntrinsic {
  public:
-    ScriptIntrinsicBlend(sp<RS> rs, sp <const Element> e);
+    ScriptIntrinsicBlend(sp<RS> rs, sp<const Element> e);
     void blendClear(sp<Allocation> in, sp<Allocation> out);
     void blendSrc(sp<Allocation> in, sp<Allocation> out);
     void blendDst(sp<Allocation> in, sp<Allocation> out);
@@ -685,11 +691,50 @@
 
 class ScriptIntrinsicBlur : public ScriptIntrinsic {
  public:
-    ScriptIntrinsicBlur(sp<RS> rs, sp <const Element> e);
+    ScriptIntrinsicBlur(sp<RS> rs, sp<const Element> e);
     void blur(sp<Allocation> in, sp<Allocation> out);
     void setRadius(float radius);
 };
 
+class ScriptIntrinsicColorMatrix : public ScriptIntrinsic {
+ public:
+    ScriptIntrinsicColorMatrix(sp<RS> rs, sp<const Element> e);
+    void forEach(sp<Allocation> in, sp<Allocation> out);
+    void setColorMatrix3(float* m);
+    void setColorMatrix4(float* m);
+    void setGreyscale();
+    void setRGBtoYUV();
+    void setYUVtoRGB();
+};
+
+class ScriptIntrinsicConvolve3x3 : public ScriptIntrinsic {
+ public:
+    ScriptIntrinsicConvolve3x3(sp<RS> rs, sp<const Element> e);
+    void setInput(sp<Allocation> in);
+    void forEach(sp<Allocation> out);
+    void setCoefficients(float* v);
+};
+
+class ScriptIntrinsicConvolve5x5 : public ScriptIntrinsic {
+ public:
+    ScriptIntrinsicConvolve5x5(sp<RS> rs, sp<const Element> e);
+    void setInput(sp<Allocation> in);
+    void forEach(sp<Allocation> out);
+    void setCoefficients(float* v);
+};
+
+/*class ScriptIntrinsicLUT : public ScriptIntrinsic {
+ public:
+    ScriptIntrinsicLUT(sp<RS> rs, sp<const Element> e);
+    void forEach(sp<Allocation> ain, sp<Allocation> aout);
+    void setLUT(sp<Allocation> lut);
+    };*/
+/*
+class ScriptIntrinsicYuvToRGB : public ScriptIntrinsic {
+
+};
+*/
+
  class Sampler : public BaseObj {
  private:
     Sampler(sp<RS> rs, void* id);
diff --git a/cpp/util/RefBase.h b/cpp/util/RefBase.h
new file mode 100644
index 0000000..eab26ab
--- /dev/null
+++ b/cpp/util/RefBase.h
@@ -0,0 +1,529 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RS_REF_BASE_H
+#define RS_REF_BASE_H
+
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "StrongPointer.h"
+#include "TypeHelpers.h"
+
+// ---------------------------------------------------------------------------
+namespace android{
+namespace RSC {
+
+class TextOutput;
+TextOutput& printWeakPointer(TextOutput& to, const void* val);
+
+// ---------------------------------------------------------------------------
+
+#define COMPARE_WEAK(_op_)                                      \
+inline bool operator _op_ (const sp<T>& o) const {              \
+    return m_ptr _op_ o.m_ptr;                                  \
+}                                                               \
+inline bool operator _op_ (const T* o) const {                  \
+    return m_ptr _op_ o;                                        \
+}                                                               \
+template<typename U>                                            \
+inline bool operator _op_ (const sp<U>& o) const {              \
+    return m_ptr _op_ o.m_ptr;                                  \
+}                                                               \
+template<typename U>                                            \
+inline bool operator _op_ (const U* o) const {                  \
+    return m_ptr _op_ o;                                        \
+}
+
+// ---------------------------------------------------------------------------
+class ReferenceMover;
+class ReferenceConverterBase {
+public:
+    virtual size_t getReferenceTypeSize() const = 0;
+    virtual void* getReferenceBase(void const*) const = 0;
+    inline virtual ~ReferenceConverterBase() { }
+};
+
+// ---------------------------------------------------------------------------
+
+class RefBase
+{
+public:
+            void            incStrong(const void* id) const;
+            void            decStrong(const void* id) const;
+
+            void            forceIncStrong(const void* id) const;
+
+            //! DEBUGGING ONLY: Get current strong ref count.
+            int32_t         getStrongCount() const;
+
+    class weakref_type
+    {
+    public:
+        RefBase*            refBase() const;
+
+        void                incWeak(const void* id);
+        void                decWeak(const void* id);
+
+        // acquires a strong reference if there is already one.
+        bool                attemptIncStrong(const void* id);
+
+        // acquires a weak reference if there is already one.
+        // This is not always safe. see ProcessState.cpp and BpBinder.cpp
+        // for proper use.
+        bool                attemptIncWeak(const void* id);
+
+        //! DEBUGGING ONLY: Get current weak ref count.
+        int32_t             getWeakCount() const;
+
+        //! DEBUGGING ONLY: Print references held on object.
+        void                printRefs() const;
+
+        //! DEBUGGING ONLY: Enable tracking for this object.
+        // enable -- enable/disable tracking
+        // retain -- when tracking is enable, if true, then we save a stack trace
+        //           for each reference and dereference; when retain == false, we
+        //           match up references and dereferences and keep only the
+        //           outstanding ones.
+
+        void                trackMe(bool enable, bool retain);
+    };
+
+            weakref_type*   createWeak(const void* id) const;
+
+            weakref_type*   getWeakRefs() const;
+
+            //! DEBUGGING ONLY: Print references held on object.
+    inline  void            printRefs() const { getWeakRefs()->printRefs(); }
+
+            //! DEBUGGING ONLY: Enable tracking of object.
+    inline  void            trackMe(bool enable, bool retain)
+    {
+        getWeakRefs()->trackMe(enable, retain);
+    }
+
+    typedef RefBase basetype;
+
+protected:
+                            RefBase();
+    virtual                 ~RefBase();
+
+    //! Flags for extendObjectLifetime()
+    enum {
+        OBJECT_LIFETIME_STRONG  = 0x0000,
+        OBJECT_LIFETIME_WEAK    = 0x0001,
+        OBJECT_LIFETIME_MASK    = 0x0001
+    };
+
+            void            extendObjectLifetime(int32_t mode);
+
+    //! Flags for onIncStrongAttempted()
+    enum {
+        FIRST_INC_STRONG = 0x0001
+    };
+
+    virtual void            onFirstRef();
+    virtual void            onLastStrongRef(const void* id);
+    virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);
+    virtual void            onLastWeakRef(const void* id);
+
+private:
+    friend class ReferenceMover;
+    static void moveReferences(void* d, void const* s, size_t n,
+            const ReferenceConverterBase& caster);
+
+private:
+    friend class weakref_type;
+    class weakref_impl;
+
+                            RefBase(const RefBase& o);
+            RefBase&        operator=(const RefBase& o);
+
+        weakref_impl* const mRefs;
+};
+
+// ---------------------------------------------------------------------------
+
+template <class T>
+class LightRefBase
+{
+public:
+    inline LightRefBase() : mCount(0) { }
+    inline void incStrong(__attribute__((unused)) const void* id) const {
+        __sync_fetch_and_add(&mCount, 1);
+    }
+    inline void decStrong(__attribute__((unused)) const void* id) const {
+        if (__sync_fetch_and_sub(&mCount, 1) == 1) {
+            delete static_cast<const T*>(this);
+        }
+    }
+    //! DEBUGGING ONLY: Get current strong ref count.
+    inline int32_t getStrongCount() const {
+        return mCount;
+    }
+
+    typedef LightRefBase<T> basetype;
+
+protected:
+    inline ~LightRefBase() { }
+
+private:
+    friend class ReferenceMover;
+    inline static void moveReferences(void* d, void const* s, size_t n,
+            const ReferenceConverterBase& caster) { }
+
+private:
+    mutable volatile int32_t mCount;
+};
+
+// ---------------------------------------------------------------------------
+
+template <typename T>
+class wp
+{
+public:
+    typedef typename RefBase::weakref_type weakref_type;
+
+    inline wp() : m_ptr(0) { }
+
+    wp(T* other);
+    wp(const wp<T>& other);
+    wp(const sp<T>& other);
+    template<typename U> wp(U* other);
+    template<typename U> wp(const sp<U>& other);
+    template<typename U> wp(const wp<U>& other);
+
+    ~wp();
+
+    // Assignment
+
+    wp& operator = (T* other);
+    wp& operator = (const wp<T>& other);
+    wp& operator = (const sp<T>& other);
+
+    template<typename U> wp& operator = (U* other);
+    template<typename U> wp& operator = (const wp<U>& other);
+    template<typename U> wp& operator = (const sp<U>& other);
+
+    void set_object_and_refs(T* other, weakref_type* refs);
+
+    // promotion to sp
+
+    sp<T> promote() const;
+
+    // Reset
+
+    void clear();
+
+    // Accessors
+
+    inline  weakref_type* get_refs() const { return m_refs; }
+
+    inline  T* unsafe_get() const { return m_ptr; }
+
+    // Operators
+
+    COMPARE_WEAK(==)
+    COMPARE_WEAK(!=)
+    COMPARE_WEAK(>)
+    COMPARE_WEAK(<)
+    COMPARE_WEAK(<=)
+    COMPARE_WEAK(>=)
+
+    inline bool operator == (const wp<T>& o) const {
+        return (m_ptr == o.m_ptr) && (m_refs == o.m_refs);
+    }
+    template<typename U>
+    inline bool operator == (const wp<U>& o) const {
+        return m_ptr == o.m_ptr;
+    }
+
+    inline bool operator > (const wp<T>& o) const {
+        return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
+    }
+    template<typename U>
+    inline bool operator > (const wp<U>& o) const {
+        return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
+    }
+
+    inline bool operator < (const wp<T>& o) const {
+        return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
+    }
+    template<typename U>
+    inline bool operator < (const wp<U>& o) const {
+        return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
+    }
+                         inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; }
+    template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); }
+                         inline bool operator <= (const wp<T>& o) const { return !operator > (o); }
+    template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); }
+                         inline bool operator >= (const wp<T>& o) const { return !operator < (o); }
+    template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); }
+
+private:
+    template<typename Y> friend class sp;
+    template<typename Y> friend class wp;
+
+    T*              m_ptr;
+    weakref_type*   m_refs;
+};
+
+template <typename T>
+TextOutput& operator<<(TextOutput& to, const wp<T>& val);
+
+#undef COMPARE_WEAK
+
+// ---------------------------------------------------------------------------
+// No user serviceable parts below here.
+
+template<typename T>
+wp<T>::wp(T* other)
+    : m_ptr(other)
+{
+    if (other) m_refs = other->createWeak(this);
+}
+
+template<typename T>
+wp<T>::wp(const wp<T>& other)
+    : m_ptr(other.m_ptr), m_refs(other.m_refs)
+{
+    if (m_ptr) m_refs->incWeak(this);
+}
+
+template<typename T>
+wp<T>::wp(const sp<T>& other)
+    : m_ptr(other.m_ptr)
+{
+    if (m_ptr) {
+        m_refs = m_ptr->createWeak(this);
+    }
+}
+
+template<typename T> template<typename U>
+wp<T>::wp(U* other)
+    : m_ptr(other)
+{
+    if (other) m_refs = other->createWeak(this);
+}
+
+template<typename T> template<typename U>
+wp<T>::wp(const wp<U>& other)
+    : m_ptr(other.m_ptr)
+{
+    if (m_ptr) {
+        m_refs = other.m_refs;
+        m_refs->incWeak(this);
+    }
+}
+
+template<typename T> template<typename U>
+wp<T>::wp(const sp<U>& other)
+    : m_ptr(other.m_ptr)
+{
+    if (m_ptr) {
+        m_refs = m_ptr->createWeak(this);
+    }
+}
+
+template<typename T>
+wp<T>::~wp()
+{
+    if (m_ptr) m_refs->decWeak(this);
+}
+
+template<typename T>
+wp<T>& wp<T>::operator = (T* other)
+{
+    weakref_type* newRefs =
+        other ? other->createWeak(this) : 0;
+    if (m_ptr) m_refs->decWeak(this);
+    m_ptr = other;
+    m_refs = newRefs;
+    return *this;
+}
+
+template<typename T>
+wp<T>& wp<T>::operator = (const wp<T>& other)
+{
+    weakref_type* otherRefs(other.m_refs);
+    T* otherPtr(other.m_ptr);
+    if (otherPtr) otherRefs->incWeak(this);
+    if (m_ptr) m_refs->decWeak(this);
+    m_ptr = otherPtr;
+    m_refs = otherRefs;
+    return *this;
+}
+
+template<typename T>
+wp<T>& wp<T>::operator = (const sp<T>& other)
+{
+    weakref_type* newRefs =
+        other != NULL ? other->createWeak(this) : 0;
+    T* otherPtr(other.m_ptr);
+    if (m_ptr) m_refs->decWeak(this);
+    m_ptr = otherPtr;
+    m_refs = newRefs;
+    return *this;
+}
+
+template<typename T> template<typename U>
+wp<T>& wp<T>::operator = (U* other)
+{
+    weakref_type* newRefs =
+        other ? other->createWeak(this) : 0;
+    if (m_ptr) m_refs->decWeak(this);
+    m_ptr = other;
+    m_refs = newRefs;
+    return *this;
+}
+
+template<typename T> template<typename U>
+wp<T>& wp<T>::operator = (const wp<U>& other)
+{
+    weakref_type* otherRefs(other.m_refs);
+    U* otherPtr(other.m_ptr);
+    if (otherPtr) otherRefs->incWeak(this);
+    if (m_ptr) m_refs->decWeak(this);
+    m_ptr = otherPtr;
+    m_refs = otherRefs;
+    return *this;
+}
+
+template<typename T> template<typename U>
+wp<T>& wp<T>::operator = (const sp<U>& other)
+{
+    weakref_type* newRefs =
+        other != NULL ? other->createWeak(this) : 0;
+    U* otherPtr(other.m_ptr);
+    if (m_ptr) m_refs->decWeak(this);
+    m_ptr = otherPtr;
+    m_refs = newRefs;
+    return *this;
+}
+
+template<typename T>
+void wp<T>::set_object_and_refs(T* other, weakref_type* refs)
+{
+    if (other) refs->incWeak(this);
+    if (m_ptr) m_refs->decWeak(this);
+    m_ptr = other;
+    m_refs = refs;
+}
+
+template<typename T>
+sp<T> wp<T>::promote() const
+{
+    sp<T> result;
+    if (m_ptr && m_refs->attemptIncStrong(&result)) {
+        result.set_pointer(m_ptr);
+    }
+    return result;
+}
+
+template<typename T>
+void wp<T>::clear()
+{
+    if (m_ptr) {
+        m_refs->decWeak(this);
+        m_ptr = 0;
+    }
+}
+
+template <typename T>
+inline TextOutput& operator<<(TextOutput& to, const wp<T>& val)
+{
+    return printWeakPointer(to, val.unsafe_get());
+}
+
+// ---------------------------------------------------------------------------
+
+// this class just serves as a namespace so TYPE::moveReferences can stay
+// private.
+
+class ReferenceMover {
+    // StrongReferenceCast and WeakReferenceCast do the impedance matching
+    // between the generic (void*) implementation in Refbase and the strongly typed
+    // template specializations below.
+
+    template <typename TYPE>
+    struct StrongReferenceCast : public ReferenceConverterBase {
+        virtual size_t getReferenceTypeSize() const { return sizeof( sp<TYPE> ); }
+        virtual void* getReferenceBase(void const* p) const {
+            sp<TYPE> const* sptr(reinterpret_cast<sp<TYPE> const*>(p));
+            return static_cast<typename TYPE::basetype *>(sptr->get());
+        }
+    };
+
+    template <typename TYPE>
+    struct WeakReferenceCast : public ReferenceConverterBase {
+        virtual size_t getReferenceTypeSize() const { return sizeof( wp<TYPE> ); }
+        virtual void* getReferenceBase(void const* p) const {
+            wp<TYPE> const* sptr(reinterpret_cast<wp<TYPE> const*>(p));
+            return static_cast<typename TYPE::basetype *>(sptr->unsafe_get());
+        }
+    };
+
+public:
+    template<typename TYPE> static inline
+    void move_references(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
+        memmove(d, s, n*sizeof(sp<TYPE>));
+        StrongReferenceCast<TYPE> caster;
+        TYPE::moveReferences(d, s, n, caster);
+    }
+    template<typename TYPE> static inline
+    void move_references(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
+        memmove(d, s, n*sizeof(wp<TYPE>));
+        WeakReferenceCast<TYPE> caster;
+        TYPE::moveReferences(d, s, n, caster);
+    }
+};
+
+// specialization for moving sp<> and wp<> types.
+// these are used by the [Sorted|Keyed]Vector<> implementations
+// sp<> and wp<> need to be handled specially, because they do not
+// have trivial copy operation in the general case (see RefBase.cpp
+// when DEBUG ops are enabled), but can be implemented very
+// efficiently in most cases.
+
+template<typename TYPE> inline
+void move_forward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
+    ReferenceMover::move_references(d, s, n);
+}
+
+template<typename TYPE> inline
+void move_backward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
+    ReferenceMover::move_references(d, s, n);
+}
+
+template<typename TYPE> inline
+void move_forward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
+    ReferenceMover::move_references(d, s, n);
+}
+
+template<typename TYPE> inline
+void move_backward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
+    ReferenceMover::move_references(d, s, n);
+}
+
+
+}; // namespace RSC
+}; // namespace android
+// ---------------------------------------------------------------------------
+
+#endif // RS_REF_BASE_H
diff --git a/cpp/util/StrongPointer.h b/cpp/util/StrongPointer.h
new file mode 100644
index 0000000..0f68615
--- /dev/null
+++ b/cpp/util/StrongPointer.h
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RS_STRONG_POINTER_H
+#define RS_STRONG_POINTER_H
+
+//#include <cutils/atomic.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <stdlib.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace RSC {
+
+class TextOutput;
+TextOutput& printStrongPointer(TextOutput& to, const void* val);
+
+template<typename T> class wp;
+
+// ---------------------------------------------------------------------------
+
+#define COMPARE(_op_)                                           \
+inline bool operator _op_ (const sp<T>& o) const {              \
+    return m_ptr _op_ o.m_ptr;                                  \
+}                                                               \
+inline bool operator _op_ (const T* o) const {                  \
+    return m_ptr _op_ o;                                        \
+}                                                               \
+template<typename U>                                            \
+inline bool operator _op_ (const sp<U>& o) const {              \
+    return m_ptr _op_ o.m_ptr;                                  \
+}                                                               \
+template<typename U>                                            \
+inline bool operator _op_ (const U* o) const {                  \
+    return m_ptr _op_ o;                                        \
+}                                                               \
+inline bool operator _op_ (const wp<T>& o) const {              \
+    return m_ptr _op_ o.m_ptr;                                  \
+}                                                               \
+template<typename U>                                            \
+inline bool operator _op_ (const wp<U>& o) const {              \
+    return m_ptr _op_ o.m_ptr;                                  \
+}
+
+// ---------------------------------------------------------------------------
+
+template <typename T>
+class sp
+{
+public:
+    inline sp() : m_ptr(0) { }
+
+    sp(T* other);
+    sp(const sp<T>& other);
+    template<typename U> sp(U* other);
+    template<typename U> sp(const sp<U>& other);
+
+    ~sp();
+
+    // Assignment
+
+    sp& operator = (T* other);
+    sp& operator = (const sp<T>& other);
+
+    template<typename U> sp& operator = (const sp<U>& other);
+    template<typename U> sp& operator = (U* other);
+
+    //! Special optimization for use by ProcessState (and nobody else).
+    void force_set(T* other);
+
+    // Reset
+
+    void clear();
+
+    // Accessors
+
+    inline  T&      operator* () const  { return *m_ptr; }
+    inline  T*      operator-> () const { return m_ptr;  }
+    inline  T*      get() const         { return m_ptr; }
+
+    // Operators
+
+    COMPARE(==)
+    COMPARE(!=)
+    COMPARE(>)
+    COMPARE(<)
+    COMPARE(<=)
+    COMPARE(>=)
+
+private:
+    template<typename Y> friend class sp;
+    template<typename Y> friend class wp;
+    void set_pointer(T* ptr);
+    T* m_ptr;
+};
+
+#undef COMPARE
+
+template <typename T>
+TextOutput& operator<<(TextOutput& to, const sp<T>& val);
+
+// ---------------------------------------------------------------------------
+// No user serviceable parts below here.
+
+template<typename T>
+sp<T>::sp(T* other)
+: m_ptr(other)
+  {
+    if (other) other->incStrong(this);
+  }
+
+template<typename T>
+sp<T>::sp(const sp<T>& other)
+: m_ptr(other.m_ptr)
+  {
+    if (m_ptr) m_ptr->incStrong(this);
+  }
+
+template<typename T> template<typename U>
+sp<T>::sp(U* other) : m_ptr(other)
+{
+    if (other) ((T*)other)->incStrong(this);
+}
+
+template<typename T> template<typename U>
+sp<T>::sp(const sp<U>& other)
+: m_ptr(other.m_ptr)
+  {
+    if (m_ptr) m_ptr->incStrong(this);
+  }
+
+template<typename T>
+sp<T>::~sp()
+{
+    if (m_ptr) m_ptr->decStrong(this);
+}
+
+template<typename T>
+sp<T>& sp<T>::operator = (const sp<T>& other) {
+    T* otherPtr(other.m_ptr);
+    if (otherPtr) otherPtr->incStrong(this);
+    if (m_ptr) m_ptr->decStrong(this);
+    m_ptr = otherPtr;
+    return *this;
+}
+
+template<typename T>
+sp<T>& sp<T>::operator = (T* other)
+{
+    if (other) other->incStrong(this);
+    if (m_ptr) m_ptr->decStrong(this);
+    m_ptr = other;
+    return *this;
+}
+
+template<typename T> template<typename U>
+sp<T>& sp<T>::operator = (const sp<U>& other)
+{
+    T* otherPtr(other.m_ptr);
+    if (otherPtr) otherPtr->incStrong(this);
+    if (m_ptr) m_ptr->decStrong(this);
+    m_ptr = otherPtr;
+    return *this;
+}
+
+template<typename T> template<typename U>
+sp<T>& sp<T>::operator = (U* other)
+{
+    if (other) ((T*)other)->incStrong(this);
+    if (m_ptr) m_ptr->decStrong(this);
+    m_ptr = other;
+    return *this;
+}
+
+template<typename T>
+void sp<T>::force_set(T* other)
+{
+    other->forceIncStrong(this);
+    m_ptr = other;
+}
+
+template<typename T>
+void sp<T>::clear()
+{
+    if (m_ptr) {
+        m_ptr->decStrong(this);
+        m_ptr = 0;
+    }
+}
+
+template<typename T>
+void sp<T>::set_pointer(T* ptr) {
+    m_ptr = ptr;
+}
+
+template <typename T>
+inline TextOutput& operator<<(TextOutput& to, const sp<T>& val)
+{
+    return printStrongPointer(to, val.get());
+}
+
+}; // namespace RSC
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // RS_STRONG_POINTER_H
diff --git a/cpp/util/TypeHelpers.h b/cpp/util/TypeHelpers.h
new file mode 100644
index 0000000..33a5201
--- /dev/null
+++ b/cpp/util/TypeHelpers.h
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RS_TYPE_HELPERS_H
+#define RS_TYPE_HELPERS_H
+
+#include <new>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace RSC {
+
+/*
+ * Types traits
+ */
+
+template <typename T> struct trait_trivial_ctor { enum { value = false }; };
+template <typename T> struct trait_trivial_dtor { enum { value = false }; };
+template <typename T> struct trait_trivial_copy { enum { value = false }; };
+template <typename T> struct trait_trivial_move { enum { value = false }; };
+template <typename T> struct trait_pointer      { enum { value = false }; };
+template <typename T> struct trait_pointer<T*>  { enum { value = true }; };
+
+template <typename TYPE>
+struct traits {
+    enum {
+        // whether this type is a pointer
+        is_pointer          = trait_pointer<TYPE>::value,
+        // whether this type's constructor is a no-op
+        has_trivial_ctor    = is_pointer || trait_trivial_ctor<TYPE>::value,
+        // whether this type's destructor is a no-op
+        has_trivial_dtor    = is_pointer || trait_trivial_dtor<TYPE>::value,
+        // whether this type type can be copy-constructed with memcpy
+        has_trivial_copy    = is_pointer || trait_trivial_copy<TYPE>::value,
+        // whether this type can be moved with memmove
+        has_trivial_move    = is_pointer || trait_trivial_move<TYPE>::value
+    };
+};
+
+template <typename T, typename U>
+struct aggregate_traits {
+    enum {
+        is_pointer          = false,
+        has_trivial_ctor    =
+            traits<T>::has_trivial_ctor && traits<U>::has_trivial_ctor,
+        has_trivial_dtor    =
+            traits<T>::has_trivial_dtor && traits<U>::has_trivial_dtor,
+        has_trivial_copy    =
+            traits<T>::has_trivial_copy && traits<U>::has_trivial_copy,
+        has_trivial_move    =
+            traits<T>::has_trivial_move && traits<U>::has_trivial_move
+    };
+};
+
+#define RS_TRIVIAL_CTOR_TRAIT( T ) \
+    template<> struct trait_trivial_ctor< T >   { enum { value = true }; };
+
+#define RS_TRIVIAL_DTOR_TRAIT( T ) \
+    template<> struct trait_trivial_dtor< T >   { enum { value = true }; };
+
+#define RS_TRIVIAL_COPY_TRAIT( T ) \
+    template<> struct trait_trivial_copy< T >   { enum { value = true }; };
+
+#define RS_TRIVIAL_MOVE_TRAIT( T ) \
+    template<> struct trait_trivial_move< T >   { enum { value = true }; };
+
+#define RS_BASIC_TYPES_TRAITS( T ) \
+    RS_TRIVIAL_CTOR_TRAIT( T ) \
+    RS_TRIVIAL_DTOR_TRAIT( T ) \
+    RS_TRIVIAL_COPY_TRAIT( T ) \
+    RS_TRIVIAL_MOVE_TRAIT( T )
+
+// ---------------------------------------------------------------------------
+
+/*
+ * basic types traits
+ */
+
+RS_BASIC_TYPES_TRAITS( void )
+RS_BASIC_TYPES_TRAITS( bool )
+RS_BASIC_TYPES_TRAITS( char )
+RS_BASIC_TYPES_TRAITS( unsigned char )
+RS_BASIC_TYPES_TRAITS( short )
+RS_BASIC_TYPES_TRAITS( unsigned short )
+RS_BASIC_TYPES_TRAITS( int )
+RS_BASIC_TYPES_TRAITS( unsigned int )
+RS_BASIC_TYPES_TRAITS( long )
+RS_BASIC_TYPES_TRAITS( unsigned long )
+RS_BASIC_TYPES_TRAITS( long long )
+RS_BASIC_TYPES_TRAITS( unsigned long long )
+RS_BASIC_TYPES_TRAITS( float )
+RS_BASIC_TYPES_TRAITS( double )
+
+// ---------------------------------------------------------------------------
+
+
+/*
+ * compare and order types
+ */
+
+template<typename TYPE> inline
+int strictly_order_type(const TYPE& lhs, const TYPE& rhs) {
+    return (lhs < rhs) ? 1 : 0;
+}
+
+template<typename TYPE> inline
+int compare_type(const TYPE& lhs, const TYPE& rhs) {
+    return strictly_order_type(rhs, lhs) - strictly_order_type(lhs, rhs);
+}
+
+/*
+ * create, destroy, copy and move types...
+ */
+
+template<typename TYPE> inline
+void construct_type(TYPE* p, size_t n) {
+    if (!traits<TYPE>::has_trivial_ctor) {
+        while (n--) {
+            new(p++) TYPE;
+        }
+    }
+}
+
+template<typename TYPE> inline
+void destroy_type(TYPE* p, size_t n) {
+    if (!traits<TYPE>::has_trivial_dtor) {
+        while (n--) {
+            p->~TYPE();
+            p++;
+        }
+    }
+}
+
+template<typename TYPE> inline
+void copy_type(TYPE* d, const TYPE* s, size_t n) {
+    if (!traits<TYPE>::has_trivial_copy) {
+        while (n--) {
+            new(d) TYPE(*s);
+            d++, s++;
+        }
+    } else {
+        memcpy(d,s,n*sizeof(TYPE));
+    }
+}
+
+template<typename TYPE> inline
+void splat_type(TYPE* where, const TYPE* what, size_t n) {
+    if (!traits<TYPE>::has_trivial_copy) {
+        while (n--) {
+            new(where) TYPE(*what);
+            where++;
+        }
+    } else {
+        while (n--) {
+            *where++ = *what;
+        }
+    }
+}
+
+template<typename TYPE> inline
+void move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) {
+    if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy)
+            || traits<TYPE>::has_trivial_move)
+    {
+        memmove(d,s,n*sizeof(TYPE));
+    } else {
+        d += n;
+        s += n;
+        while (n--) {
+            --d, --s;
+            if (!traits<TYPE>::has_trivial_copy) {
+                new(d) TYPE(*s);
+            } else {
+                *d = *s;
+            }
+            if (!traits<TYPE>::has_trivial_dtor) {
+                s->~TYPE();
+            }
+        }
+    }
+}
+
+template<typename TYPE> inline
+void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
+    if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy)
+            || traits<TYPE>::has_trivial_move)
+    {
+        memmove(d,s,n*sizeof(TYPE));
+    } else {
+        while (n--) {
+            if (!traits<TYPE>::has_trivial_copy) {
+                new(d) TYPE(*s);
+            } else {
+                *d = *s;
+            }
+            if (!traits<TYPE>::has_trivial_dtor) {
+                s->~TYPE();
+            }
+            d++, s++;
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+/*
+ * a key/value pair
+ */
+
+template <typename KEY, typename VALUE>
+struct key_value_pair_t {
+    typedef KEY key_t;
+    typedef VALUE value_t;
+
+    KEY     key;
+    VALUE   value;
+    key_value_pair_t() { }
+    key_value_pair_t(const key_value_pair_t& o) : key(o.key), value(o.value) { }
+    key_value_pair_t(const KEY& k, const VALUE& v) : key(k), value(v)  { }
+    key_value_pair_t(const KEY& k) : key(k) { }
+    inline bool operator < (const key_value_pair_t& o) const {
+        return strictly_order_type(key, o.key);
+    }
+    inline const KEY& getKey() const {
+        return key;
+    }
+    inline const VALUE& getValue() const {
+        return value;
+    }
+};
+
+template <typename K, typename V>
+struct trait_trivial_ctor< key_value_pair_t<K, V> >
+{ enum { value = aggregate_traits<K,V>::has_trivial_ctor }; };
+template <typename K, typename V>
+struct trait_trivial_dtor< key_value_pair_t<K, V> >
+{ enum { value = aggregate_traits<K,V>::has_trivial_dtor }; };
+template <typename K, typename V>
+struct trait_trivial_copy< key_value_pair_t<K, V> >
+{ enum { value = aggregate_traits<K,V>::has_trivial_copy }; };
+template <typename K, typename V>
+struct trait_trivial_move< key_value_pair_t<K, V> >
+{ enum { value = aggregate_traits<K,V>::has_trivial_move }; };
+
+// ---------------------------------------------------------------------------
+
+/*
+ * Hash codes.
+ */
+typedef uint32_t hash_t;
+
+template <typename TKey>
+hash_t hash_type(const TKey& key);
+
+/* Built-in hash code specializations.
+ * Assumes pointers are 32bit. */
+#define RS_INT32_HASH(T) \
+        template <> inline hash_t hash_type(const T& value) { return hash_t(value); }
+#define RS_INT64_HASH(T) \
+        template <> inline hash_t hash_type(const T& value) { \
+                return hash_t((value >> 32) ^ value); }
+#define RS_REINTERPRET_HASH(T, R) \
+        template <> inline hash_t hash_type(const T& value) { \
+                return hash_type(*reinterpret_cast<const R*>(&value)); }
+
+RS_INT32_HASH(bool)
+RS_INT32_HASH(int8_t)
+RS_INT32_HASH(uint8_t)
+RS_INT32_HASH(int16_t)
+RS_INT32_HASH(uint16_t)
+RS_INT32_HASH(int32_t)
+RS_INT32_HASH(uint32_t)
+RS_INT64_HASH(int64_t)
+RS_INT64_HASH(uint64_t)
+RS_REINTERPRET_HASH(float, uint32_t)
+RS_REINTERPRET_HASH(double, uint64_t)
+
+template <typename T> inline hash_t hash_type(T* const & value) {
+    return hash_type(uintptr_t(value));
+}
+
+}; // namespace RSC
+}; // namespace android
+// ---------------------------------------------------------------------------
+
+#endif // RS_TYPE_HELPERS_H