diff --git a/vehicle/2.0/IVehicle.hal b/vehicle/2.0/IVehicle.hal
index 0885539..4c02447 100644
--- a/vehicle/2.0/IVehicle.hal
+++ b/vehicle/2.0/IVehicle.hal
@@ -64,11 +64,11 @@
    * Clients must be able to subscribe to multiple properties at a time
    * depending on data provided in options argument.
    *
-   * @param listener This client must be called on aproperiate event.
+   * @param listener This client must be called on appropriate event.
    * @param options List of options to subscribe. SubscribeOption contains
-   *                information such as propery Id, area Id, sample rate, etc.
+   *                information such as property Id, area Id, sample rate, etc.
    */
-  subscribe(IVehicleCallback listener, vec<SubscribeOptions> options)
+  subscribe(IVehicleCallback callback, vec<SubscribeOptions> options)
           generates (StatusCode status);
 
   /**
@@ -77,7 +77,8 @@
    * If this client wasn't subscribed to the given property, this method
    * must return StatusCode::INVALID_ARGUMENT.
    */
-  unsubscribe(VehicleProperty propId) generates (StatusCode status);
+  unsubscribe(IVehicleCallback callback, VehicleProperty propId)
+          generates (StatusCode status);
 
   /**
    * Print out debugging state for the vehicle hal.
@@ -91,7 +92,7 @@
    * primitives used (such as mutex locks or semaphores) must be acquired
    * with a timeout.
    *
-   * TODO(pavelm): we cannot use handle here due to Java compatability, it's
+   * TODO(pavelm): we cannot use handle here due to Java compatibility, it's
    * better to pass file descriptor and write debug data directly in vehicle HAL
    * rather than passing back a string.
    */
diff --git a/vehicle/2.0/IVehicleCallback.hal b/vehicle/2.0/IVehicleCallback.hal
index 1e9034f..5c1042b 100644
--- a/vehicle/2.0/IVehicleCallback.hal
+++ b/vehicle/2.0/IVehicleCallback.hal
@@ -29,7 +29,7 @@
      *
      * @param values that has been updated.
      */
-    onPropertyEvent(vec<VehiclePropValue> propValues);
+    oneway onPropertyEvent(vec<VehiclePropValue> propValues);
 
     /*
      * This method gets called if the client was susbscribed to a property using
@@ -40,7 +40,7 @@
      *
      * @param value Value that was set by a client.
      */
-    onPropertySet(VehiclePropValue propValue);
+    oneway onPropertySet(VehiclePropValue propValue);
 
     /*
      * Called by HAL server when error condition has occurred.
@@ -50,7 +50,7 @@
      * a generic error, this value should be VehicleProperty::INVALID.
      * @param operation Represent the operation where the error has happened.
      */
-    onError(StatusCode errorCode,
-            VehicleProperty propId,
-            VehiclePropertyOperation operation);
+    oneway onError(StatusCode errorCode,
+                   VehicleProperty propId,
+                   VehiclePropertyOperation operation);
 };
diff --git a/vehicle/2.0/default/Android.mk b/vehicle/2.0/default/Android.mk
index a30d753..e14cb19 100644
--- a/vehicle/2.0/default/Android.mk
+++ b/vehicle/2.0/default/Android.mk
@@ -14,29 +14,92 @@
 
 LOCAL_PATH := $(call my-dir)
 
+module_prefix = android.hardware.vehicle@2.0
+
+###############################################################################
+# Vehicle reference implementation lib
+###############################################################################
 include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.vehicle@2.0-impl
-# TODO(pavelm): add LOCAL_INIT_RC
-LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_MODULE := $(module_prefix)-manager-lib
 LOCAL_SRC_FILES := \
-    Vehicle.cpp \
-    VehicleCallback.cpp \
+    vehicle_hal_manager/SubscriptionManager.cpp \
+    vehicle_hal_manager/VehicleHalManager.cpp \
+    vehicle_hal_manager/VehicleCallback.cpp \
 
 LOCAL_SHARED_LIBRARIES := \
+    liblog \
+    libbinder \
     libhidl \
     libhwbinder \
     libutils \
-    android.hardware.vehicle@2.0 \
+    $(module_prefix) \
 
-include $(BUILD_SHARED_LIBRARY)
+include $(BUILD_STATIC_LIBRARY)
 
-
+###############################################################################
+# Vehicle default VehicleHAL implementation
+###############################################################################
 include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.vehicle@2.0-service
+
+LOCAL_MODULE:= $(module_prefix)-default-impl-lib
+LOCAL_SRC_FILES:= \
+    impl/DefaultVehicleHal.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+    liblog \
+    libbinder \
+    libhidl \
+    libhwbinder \
+    libutils \
+    $(module_prefix) \
+
+include $(BUILD_STATIC_LIBRARY)
+
+
+###############################################################################
+# Vehicle reference implementation unit tests
+###############################################################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= $(module_prefix)-manager-unit-tests
+
+LOCAL_WHOLE_STATIC_LIBRARIES := $(module_prefix)-manager-lib
+
+LOCAL_SRC_FILES:= \
+    tests/VehicleObjectPool_test.cpp \
+    tests/VehiclePropConfigIndex_test.cpp \
+    tests/SubscriptionManager_test.cpp \
+    tests/VehicleHalManager_test.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+    liblog \
+    libbinder \
+    libhidl \
+    libhwbinder \
+    libutils \
+    $(module_prefix) \
+
+LOCAL_CFLAGS += -Wall -Wextra
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_NATIVE_TEST)
+
+
+###############################################################################
+# Vehicle HAL service
+###############################################################################
+include $(CLEAR_VARS)
+LOCAL_MODULE := $(module_prefix)-service
 LOCAL_MODULE_RELATIVE_PATH := hw
+# TODO(pavelm): add LOCAL_INIT_RC
+
 LOCAL_SRC_FILES := \
     VehicleService.cpp
 
+LOCAL_WHOLE_STATIC_LIBRARIES := \
+    $(module_prefix)-manager-lib \
+    $(module_prefix)-default-impl-lib \
+
 LOCAL_SHARED_LIBRARIES := \
     liblog \
     libbinder \
diff --git a/vehicle/2.0/default/Vehicle.cpp b/vehicle/2.0/default/Vehicle.cpp
deleted file mode 100644
index a4933df..0000000
--- a/vehicle/2.0/default/Vehicle.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2016 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.
- */
-
-#include "Vehicle.h"
-#include "VehicleUtils.h"
-
-#include <utils/SystemClock.h>
-
-namespace android {
-namespace hardware {
-namespace vehicle {
-namespace V2_0 {
-namespace implementation {
-
-const VehiclePropConfig kVehicleProperties[] = {
-    {
-        .prop = VehicleProperty::INFO_MAKE,
-        .access = VehiclePropertyAccess::READ,
-        .changeMode = VehiclePropertyChangeMode::STATIC,
-        .permissionModel = VehiclePermissionModel::OEM_ONLY,
-        .configString = init_hidl_string("Some=configuration,options=if,you=have,any=?"),
-    },
-
-    {
-        .prop = VehicleProperty::HVAC_FAN_SPEED,
-        .access = VehiclePropertyAccess::READ_WRITE,
-        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
-        .supportedAreas = static_cast<int32_t>(
-               VehicleAreaZone::ROW_1_LEFT | VehicleAreaZone::ROW_1_RIGHT),
-        .areaConfigs = init_hidl_vec({
-                VehicleAreaConfig {
-                    .areaId = enum_val(VehicleAreaZone::ROW_2_LEFT),
-                    .minInt32Value = 1,
-                    .maxInt32Value = 7},
-                VehicleAreaConfig {
-                    .areaId = enum_val(VehicleAreaZone::ROW_1_RIGHT),
-                    .minInt32Value = 1,
-                    .maxInt32Value = 5,
-                }
-        }),
-    },
-
-    {
-        .prop = VehicleProperty::INFO_FUEL_CAPACITY,
-        .access = VehiclePropertyAccess::READ,
-        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .permissionModel = VehiclePermissionModel::OEM_ONLY,
-        .areaConfigs = init_hidl_vec({
-                VehicleAreaConfig {
-                    .minFloatValue = 0,
-                    .maxFloatValue = 1.0
-                }
-        })
-    }
-};
-
-const char kInfoMake[] = "Android Super Car";
-
-
-Return<void> Vehicle::getAllPropConfigs(getAllPropConfigs_cb _hidl_cb)  {
-    hidl_vec<VehiclePropConfig> configs;
-
-    configs.setToExternal(const_cast<VehiclePropConfig*>(kVehicleProperties),
-                          arraysize(kVehicleProperties));
-
-    _hidl_cb(configs);
-    return Void();
-}
-
-Return<void> Vehicle::getPropConfigs(const hidl_vec<VehicleProperty>& properties,
-                                     getAllPropConfigs_cb _hidl_cb)  {
-    // TODO(pavelm): add default implementation
-    hidl_vec<VehiclePropConfig> configs;
-    _hidl_cb(configs);
-    return Void();
-}
-
-Return<void> Vehicle::get(VehicleProperty propId, int32_t areaId, get_cb _hidl_cb)  {
-    VehiclePropValue v {
-        .prop = propId,
-        .areaId = areaId,
-        .timestamp = elapsedRealtimeNano(),
-    };
-
-    StatusCode status = StatusCode::OK;
-
-    if (propId == VehicleProperty::INFO_MAKE) {
-        v.value.stringValue.setToExternal(kInfoMake, strlen(kInfoMake));
-    } else if (propId == VehicleProperty::HVAC_FAN_SPEED) {
-        v.value.int32Values = init_hidl_vec({42});
-    } else {
-        status = StatusCode::INVALID_ARG;
-    }
-
-    _hidl_cb(status, v);
-
-    return Void();
-}
-
-Return<StatusCode> Vehicle::set(const VehiclePropValue& value)  {
-    // TODO(pavelm): add default implementation
-    return StatusCode::OK;
-}
-
-Return<StatusCode> Vehicle::subscribe(const sp<IVehicleCallback>& listener,
-                                   const hidl_vec<SubscribeOptions>& options)  {
-    // TODO(pavelm): add default implementation
-    return StatusCode::OK;
-}
-
-Return<StatusCode> Vehicle::unsubscribe(VehicleProperty propId)  {
-    // TODO(pavelm): add default implementation
-    return StatusCode::OK;
-}
-
-Return<void> Vehicle::debugDump(debugDump_cb _hidl_cb) {
-    hidl_string debug;
-    debug = "Put debug data here";
-
-    _hidl_cb(debug);
-
-    return Void();
-}
-
-IVehicle* HIDL_FETCH_IVehicle(const char* /* name */) {
-    return new Vehicle();
-}
-
-} // namespace implementation
-}  // namespace V2_0
-}  // namespace vehicle
-}  // namespace hardware
-}  // namespace android
diff --git a/vehicle/2.0/default/Vehicle.h b/vehicle/2.0/default/Vehicle.h
deleted file mode 100644
index c0fe03e..0000000
--- a/vehicle/2.0/default/Vehicle.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2016 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 HIDL_GENERATED_android_hardware_vehicle_V2_0_Vehicle_H_
-#define HIDL_GENERATED_android_hardware_vehicle_V2_0_Vehicle_H_
-
-#include <android/hardware/vehicle/2.0/IVehicle.h>
-#include <hidl/Status.h>
-
-#include <hidl/MQDescriptor.h>
-namespace android {
-namespace hardware {
-namespace vehicle {
-namespace V2_0 {
-namespace implementation {
-
-using ::android::hardware::vehicle::V2_0::IVehicle;
-using ::android::hardware::vehicle::V2_0::IVehicleCallback;
-using ::android::hardware::vehicle::V2_0::SubscribeOptions;
-using ::android::hardware::vehicle::V2_0::VehiclePropConfig;
-using ::android::hardware::vehicle::V2_0::VehiclePropValue;
-using ::android::hardware::vehicle::V2_0::VehicleProperty;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::hidl_string;
-using ::android::sp;
-
-struct Vehicle : public IVehicle {
-    // Methods from ::android::hardware::vehicle::V2_0::IVehicle follow.
-    Return<void> getAllPropConfigs(getAllPropConfigs_cb _hidl_cb)  override;
-    Return<void> getPropConfigs(const hidl_vec<VehicleProperty>& properties, getPropConfigs_cb _hidl_cb)  override;
-    Return<void> get(VehicleProperty propId, int32_t areaId, get_cb _hidl_cb)  override;
-    Return<StatusCode> set(const VehiclePropValue& value)  override;
-    Return<StatusCode> subscribe(const sp<IVehicleCallback>& listener, const hidl_vec<SubscribeOptions>& options)  override;
-    Return<StatusCode> unsubscribe(VehicleProperty propId)  override;
-    Return<void> debugDump(debugDump_cb _hidl_cb = nullptr) override;
-};
-
-extern "C" IVehicle* HIDL_FETCH_IVehicle(const char* name);
-
-}  // namespace implementation
-}  // namespace V2_0
-}  // namespace vehicle
-}  // namespace hardware
-}  // namespace android
-
-#endif  // HIDL_GENERATED_android_hardware_vehicle_V2_0_Vehicle_H_
diff --git a/vehicle/2.0/default/VehicleHal.h b/vehicle/2.0/default/VehicleHal.h
new file mode 100644
index 0000000..89d8ef8
--- /dev/null
+++ b/vehicle/2.0/default/VehicleHal.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2016 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 android_hardware_vehicle_V2_0_VehicleHal_H_
+#define android_hardware_vehicle_V2_0_VehicleHal_H_
+
+#include <android/hardware/vehicle/2.0/IVehicle.h>
+#include "vehicle_hal_manager/VehicleObjectPool.h"
+
+
+namespace android {
+namespace hardware {
+namespace vehicle {
+namespace V2_0 {
+
+/**
+ * This is a low-level vehicle hal interface that should be implemented by
+ * Vendor.
+ */
+class VehicleHal {
+public:
+    using VehiclePropValuePtr = recyclable_ptr<VehiclePropValue>;
+
+    using HalEventFunction = std::function<void(VehiclePropValuePtr)>;
+    using HalErrorFunction = std::function<void(
+            VehicleProperty property,
+            status_t errorCode,
+            VehiclePropertyOperation operation)>;
+
+    virtual ~VehicleHal() {}
+
+    virtual std::vector<VehiclePropConfig> listProperties() = 0;
+    virtual VehiclePropValuePtr get(VehicleProperty property,
+                                    int32_t areaId,
+                                    status_t* outStatus) = 0;
+
+    virtual status_t set(const VehiclePropValue& propValue) = 0;
+
+    /**
+     * Subscribe to HAL property events. This method might be called multiple
+     * times for the same vehicle property to update subscribed areas or sample
+     * rate.
+     *
+     * @param property to subscribe
+     * @param areas a bitwise vehicle areas or 0 for all supported areas
+     * @param sampleRate sample rate in Hz for properties that support sample
+     *                   rate, e.g. for properties with
+     *                   VehiclePropertyChangeMode::CONTINUOUS
+     */
+    virtual status_t subscribe(VehicleProperty property,
+                               int32_t areas,
+                               float sampleRate) = 0;
+
+    /**
+     * Unsubscribe from HAL events for given property
+     *
+     * @param property vehicle property to unsubscribe
+     */
+    virtual status_t unsubscribe(VehicleProperty property) = 0;
+
+    /**
+     * Override this method if you need to do one-time initialization.
+     */
+    virtual void onCreate() {}
+
+    void init(
+        VehiclePropValuePool* valueObjectPool,
+        const HalEventFunction& onHalEvent,
+        const HalErrorFunction& onHalError) {
+        mValuePool = valueObjectPool;
+        mOnHalEvent = onHalEvent;
+        mOnHalError = onHalError;
+
+        onCreate();
+    }
+
+    VehiclePropValuePool* getValuePool() {
+        return mValuePool;
+    }
+protected:
+    void doHalEvent(VehiclePropValuePtr v) {
+        mOnHalEvent(std::move(v));
+    }
+
+    void doHalError(VehicleProperty property,
+                    status_t errorCode,
+                    VehiclePropertyOperation operation) {
+        mOnHalError(property, errorCode, operation);
+    }
+
+private:
+    HalEventFunction mOnHalEvent;
+    HalErrorFunction mOnHalError;
+    VehiclePropValuePool* mValuePool;
+};
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace hardware
+}  // namespace android
+
+#endif //android_hardware_vehicle_V2_0_VehicleHal_H_
diff --git a/vehicle/2.0/default/VehicleService.cpp b/vehicle/2.0/default/VehicleService.cpp
index b685977..e21dcd9 100644
--- a/vehicle/2.0/default/VehicleService.cpp
+++ b/vehicle/2.0/default/VehicleService.cpp
@@ -21,22 +21,18 @@
 
 #include <hwbinder/IPCThreadState.h>
 
-#include <android/hardware/vehicle/2.0/IVehicle.h>
+#include <vehicle_hal_manager/VehicleHalManager.h>
+#include <impl/DefaultVehicleHal.h>
 
 using namespace android;
 using namespace android::hardware;
 using namespace android::hardware::vehicle::V2_0;
 
 int main(int /* argc */, char* /* argv */ []) {
-    ALOGI("Service is starting");
-    android::sp<IVehicle> service = IVehicle::getService("Vehicle");
-    if (service.get() == NULL) {
-        ALOGE("IVehicle::getService returned NULL, exiting");
-        return 1;
-    }
+    auto hal = std::make_unique<impl::DefaultVehicleHal>();
+    auto service = std::make_unique<VehicleHalManager>(hal.get());
 
-    ALOGI("Registering as service");
-    // will register the -impl as a binderized service in this process
+    ALOGI("Registering as service...");
     service->registerAsService("Vehicle");
 
     ALOGI("Ready");
diff --git a/vehicle/2.0/default/VehicleUtils.h b/vehicle/2.0/default/VehicleUtils.h
deleted file mode 100644
index 78e34e5..0000000
--- a/vehicle/2.0/default/VehicleUtils.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2016 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 android_hardware_vehicle_V2_0_VehicleUtils_H_
-#define android_hardware_vehicle_V2_0_VehicleUtils_H_
-
-#include <hidl/HidlSupport.h>
-#include <android/hardware/vehicle/2.0/types.h>
-
-namespace android {
-namespace hardware {
-namespace vehicle {
-namespace V2_0 {
-
-hidl_string init_hidl_string(const char *cstr) {
-    hidl_string hidlString;
-    hidlString = cstr;
-    return hidlString;
-}
-
-template <typename T>
-hidl_vec<T> init_hidl_vec(std::initializer_list<T> values) {
-    hidl_vec<T> vector;
-    vector.resize(values.size());
-    size_t i = 0;
-    for (auto& c : values) {
-        vector[i++] = c;
-    }
-    return vector;
-}
-
-// OR operator for class enums. The return type will be enum's underline type.
-template <typename ENUM>
-typename std::underlying_type<ENUM>::type operator |(ENUM v1, ENUM v2) {
-    return static_cast<typename std::underlying_type<ENUM>::type>(v1)
-           | static_cast<typename std::underlying_type<ENUM>::type>(v2);
-}
-
-// AND operator for class enums. The return type will be enum's underline type.
-template <typename ENUM>
-typename std::underlying_type<ENUM>::type operator &(ENUM v1, ENUM v2) {
-    return static_cast<typename std::underlying_type<ENUM>::type>(v1)
-           | static_cast<typename std::underlying_type<ENUM>::type>(v2);
-}
-
-// Returns underlying (integer) value for given enum.
-template <typename ENUM>
-typename std::underlying_type<ENUM>::type enum_val(ENUM const value)
-{
-    return static_cast<typename std::underlying_type<ENUM>::type>(value);
-}
-
-VehiclePropertyType getPropType(VehicleProperty prop) {
-    return static_cast<VehiclePropertyType>(
-        static_cast<int32_t>(prop) & static_cast<int32_t>(VehiclePropertyType::MASK));
-}
-
-VehiclePropertyGroup getPropGroup(VehicleProperty prop) {
-    return static_cast<VehiclePropertyGroup>(
-        static_cast<int32_t>(prop) & static_cast<int32_t>(VehiclePropertyGroup::MASK));
-}
-
-bool checkPropType(VehicleProperty prop, VehiclePropertyType type) {
-    return getPropType(prop) == type;
-}
-
-bool isSystemProperty(VehicleProperty prop) {
-    return VehiclePropertyGroup::SYSTEM == getPropGroup(prop);
-}
-
-
-}  // namespace V2_0
-}  // namespace vehicle
-}  // namespace hardware
-}  // namespace android
-
-#endif android_hardware_vehicle_V2_0_VehicleUtils_H_
diff --git a/vehicle/2.0/default/impl/DefaultConfig.h b/vehicle/2.0/default/impl/DefaultConfig.h
new file mode 100644
index 0000000..6f04626
--- /dev/null
+++ b/vehicle/2.0/default/impl/DefaultConfig.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2016 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 android_hardware_vehicle_V2_0_impl_DefaultConfig_H_
+#define android_hardware_vehicle_V2_0_impl_DefaultConfig_H_
+
+#include <android/hardware/vehicle/2.0/IVehicle.h>
+
+namespace android {
+namespace hardware {
+namespace vehicle {
+namespace V2_0 {
+
+namespace impl {
+
+const VehiclePropConfig kVehicleProperties[] = {
+    {
+        .prop = VehicleProperty::INFO_MAKE,
+        .access = VehiclePropertyAccess::READ,
+        .changeMode = VehiclePropertyChangeMode::STATIC,
+        .permissionModel = VehiclePermissionModel::OEM_ONLY,
+    },
+
+    {
+        .prop = VehicleProperty::HVAC_FAN_SPEED,
+        .access = VehiclePropertyAccess::READ_WRITE,
+        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+        .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
+        .supportedAreas = static_cast<int32_t>(
+            VehicleAreaZone::ROW_1_LEFT | VehicleAreaZone::ROW_1_RIGHT),
+        .areaConfigs = init_hidl_vec({
+                 VehicleAreaConfig {
+                     .areaId = val(VehicleAreaZone::ROW_2_LEFT),
+                     .minInt32Value = 1,
+                     .maxInt32Value = 7},
+                 VehicleAreaConfig {
+                     .areaId = val(VehicleAreaZone::ROW_1_RIGHT),
+                     .minInt32Value = 1,
+                     .maxInt32Value = 5,
+                 }
+             }),
+    },
+
+    {
+        .prop = VehicleProperty::INFO_FUEL_CAPACITY,
+        .access = VehiclePropertyAccess::READ,
+        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+        .permissionModel = VehiclePermissionModel::OEM_ONLY,
+        .areaConfigs = init_hidl_vec({
+                                         VehicleAreaConfig {
+                                             .minFloatValue = 0,
+                                             .maxFloatValue = 1.0
+                                         }
+                                     })
+    },
+
+    {
+        .prop = VehicleProperty::DISPLAY_BRIGHTNESS,
+        .access = VehiclePropertyAccess::READ_WRITE,
+        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+        .permissionModel = VehiclePermissionModel::OEM_ONLY,
+        .areaConfigs = init_hidl_vec({
+                                         VehicleAreaConfig {
+                                             .minInt32Value = 0,
+                                             .maxInt32Value = 10
+                                         }
+                                     })
+    }
+};
+
+}  // impl
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace hardware
+}  // namespace android
+
+#endif // android_hardware_vehicle_V2_0_impl_DefaultConfig_H_
diff --git a/vehicle/2.0/default/impl/DefaultVehicleHal.cpp b/vehicle/2.0/default/impl/DefaultVehicleHal.cpp
new file mode 100644
index 0000000..6ca0f9f
--- /dev/null
+++ b/vehicle/2.0/default/impl/DefaultVehicleHal.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "DefaultVehicleHal.h"
+
+namespace android {
+namespace hardware {
+namespace vehicle {
+namespace V2_0 {
+
+namespace impl {
+
+VehicleHal::VehiclePropValuePtr DefaultVehicleHal::get(VehicleProperty property,
+                                                       int32_t areaId,
+                                                       status_t* outStatus) {
+    *outStatus = OK;
+
+    VehiclePropValuePtr v;
+
+    switch (property) {
+        case VehicleProperty::INFO_MAKE:
+            v = getValuePool()->obtainString("Default Car");
+            break;
+        case VehicleProperty::HVAC_FAN_SPEED:
+            int32_t value;
+            if ((*outStatus = getHvacFanSpeed(areaId, &value)) == OK) {
+                v = getValuePool()->obtainInt32(value);
+            }
+            break;
+        case VehicleProperty::INFO_FUEL_CAPACITY:
+            v = getValuePool()->obtainFloat(0.75f);
+            break;
+        case VehicleProperty::DISPLAY_BRIGHTNESS:
+            v = getValuePool()->obtainInt32(brightness);
+            break;
+        default:
+            *outStatus = BAD_VALUE;
+    }
+
+    if (*outStatus == OK && v.get() != nullptr) {
+        v->prop = property;
+        v->areaId = areaId;
+        v->timestamp = elapsedRealtimeNano();
+    }
+
+    return v;
+}
+
+status_t DefaultVehicleHal::set(const VehiclePropValue& propValue) {
+    auto property = propValue.prop;
+
+    status_t status = OK;
+
+    switch (property) {
+        case VehicleProperty::HVAC_FAN_SPEED:
+            status = setHvacFanSpeed(propValue.areaId,
+                                     propValue.value.int32Values[0]);
+            break;
+        case VehicleProperty::DISPLAY_BRIGHTNESS:
+            brightness = propValue.value.int32Values[0];
+            break;
+        default:
+            status = BAD_VALUE;
+    }
+
+    return status;
+}
+
+status_t DefaultVehicleHal::getHvacFanSpeed(int32_t areaId,
+                                            int32_t* outValue)  {
+    if (areaId == val(VehicleAreaZone::ROW_1_LEFT)) {
+        *outValue = fanSpeedRow1Left;
+    } else if (areaId == val(VehicleAreaZone::ROW_2_RIGHT)) {
+        *outValue = fanSpeedRow1Right;
+    } else {
+        return BAD_VALUE;
+    }
+    return OK;
+}
+
+status_t DefaultVehicleHal::setHvacFanSpeed(int32_t areaId, int32_t value) {
+    if (areaId == val(VehicleAreaZone::ROW_1_LEFT)) {
+        fanSpeedRow1Left = value;
+    } else if (areaId == val(VehicleAreaZone::ROW_2_RIGHT)) {
+        fanSpeedRow1Right = value;
+    } else {
+        return BAD_VALUE;
+    }
+    return OK;
+}
+
+}  // impl
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace hardware
+}  // namespace android
diff --git a/vehicle/2.0/default/impl/DefaultVehicleHal.h b/vehicle/2.0/default/impl/DefaultVehicleHal.h
new file mode 100644
index 0000000..7d0b7cb
--- /dev/null
+++ b/vehicle/2.0/default/impl/DefaultVehicleHal.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2016 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 android_hardware_vehicle_V2_0_impl_DefaultVehicleHal_H_
+#define android_hardware_vehicle_V2_0_impl_DefaultVehicleHal_H_
+
+#include <VehicleHal.h>
+#include <impl/DefaultConfig.h>
+#include <utils/SystemClock.h>
+
+namespace android {
+namespace hardware {
+namespace vehicle {
+namespace V2_0 {
+
+namespace impl {
+
+class DefaultVehicleHal : public VehicleHal {
+public:
+    std::vector<VehiclePropConfig> listProperties() override {
+        return std::vector<VehiclePropConfig>(std::begin(kVehicleProperties),
+                                              std::end(kVehicleProperties));
+    }
+
+    VehiclePropValuePtr get(VehicleProperty property,
+                            int32_t areaId,
+                            status_t* outStatus) override;
+
+    status_t set(const VehiclePropValue& propValue) override;
+
+    status_t subscribe(VehicleProperty property,
+                       int32_t areas,
+                       float sampleRate) {
+        // TODO(pavelm): implement
+        return OK;
+    }
+
+    status_t unsubscribe(VehicleProperty property) {
+        // TODO(pavelm): implement
+        return OK;
+    }
+
+private:
+    status_t getHvacFanSpeed(int32_t areaId, int32_t* outValue);
+    status_t setHvacFanSpeed(int32_t areaId, int32_t value);
+private:
+    int32_t fanSpeedRow1Left = 3;
+    int32_t fanSpeedRow1Right = 5;
+    int32_t brightness = 7;
+};
+
+}  // impl
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace hardware
+}  // namespace android
+
+
+#endif  // android_hardware_vehicle_V2_0_impl_DefaultVehicleHal_H_
diff --git a/vehicle/2.0/default/tests/SubscriptionManager_test.cpp b/vehicle/2.0/default/tests/SubscriptionManager_test.cpp
new file mode 100644
index 0000000..c3db993
--- /dev/null
+++ b/vehicle/2.0/default/tests/SubscriptionManager_test.cpp
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include <unordered_map>
+#include <iostream>
+
+#include <gtest/gtest.h>
+
+#include <vehicle_hal_manager/VehiclePropConfigIndex.h>
+#include <VehicleHal.h>
+#include <vehicle_hal_manager/VehicleHalManager.h>
+#include "vehicle_hal_manager/SubscriptionManager.h"
+
+#include "VehicleHalTestUtils.h"
+
+namespace android {
+namespace hardware {
+namespace vehicle {
+namespace V2_0 {
+
+namespace {
+
+using namespace std::placeholders;
+
+class SubscriptionManagerTest : public ::testing::Test {
+public:
+    SubscriptionManager manager;
+
+    const VehicleProperty PROP1 = VehicleProperty::HVAC_FAN_SPEED;
+    const VehicleProperty PROP2 = VehicleProperty::DISPLAY_BRIGHTNESS;
+
+    sp<IVehicleCallback> cb1 = new MockedVehicleCallback();
+    sp<IVehicleCallback> cb2 = new MockedVehicleCallback();
+    sp<IVehicleCallback> cb3 = new MockedVehicleCallback();
+
+    hidl_vec<SubscribeOptions> subscrToProp1 = init_hidl_vec(
+        {
+            SubscribeOptions {
+                .propId = PROP1,
+                .vehicleAreas = val(VehicleAreaZone::ROW_1_LEFT),
+                .flags = SubscribeFlags::HAL_EVENT
+            },
+        });
+
+    hidl_vec<SubscribeOptions> subscrToProp2 = init_hidl_vec(
+        {
+            SubscribeOptions {
+                .propId = PROP2,
+                .flags = SubscribeFlags::HAL_EVENT
+            },
+        });
+
+    hidl_vec<SubscribeOptions> subscrToProp1and2 = init_hidl_vec(
+        {
+            SubscribeOptions {
+                .propId = PROP1,
+                .vehicleAreas = val(VehicleAreaZone::ROW_1_LEFT),
+                .flags = SubscribeFlags::HAL_EVENT
+            },
+            SubscribeOptions {
+                .propId = PROP2,
+                .flags = SubscribeFlags::HAL_EVENT
+            },
+        });
+
+    static std::list<sp<IVehicleCallback>> extractCallbacks(
+            const std::list<sp<HalClient>>& clients) {
+        std::list<sp<IVehicleCallback>> callbacks;
+        for (auto c : clients) {
+            callbacks.push_back(c->getCallback());
+        }
+        return callbacks;
+    }
+
+    std::list<sp<HalClient>> clientsToProp1() {
+        return manager.getSubscribedClients(PROP1,
+                                            val(VehicleAreaZone::ROW_1_LEFT),
+                                            SubscribeFlags::DEFAULT);
+    }
+
+    std::list<sp<HalClient>> clientsToProp2() {
+        return manager.getSubscribedClients(PROP2, 0,
+                                            SubscribeFlags::DEFAULT);
+    }
+};
+
+
+TEST_F(SubscriptionManagerTest, multipleClients) {
+    manager.addOrUpdateSubscription(cb1, subscrToProp1);
+    manager.addOrUpdateSubscription(cb2, subscrToProp1);
+
+    auto clients = manager.getSubscribedClients(
+            PROP1,
+            val(VehicleAreaZone::ROW_1_LEFT),
+            SubscribeFlags::HAL_EVENT);
+
+    ASSERT_ALL_EXISTS({cb1, cb2}, extractCallbacks(clients));
+}
+
+TEST_F(SubscriptionManagerTest, negativeCases) {
+    manager.addOrUpdateSubscription(cb1, subscrToProp1);
+
+    // Wrong zone
+    auto clients = manager.getSubscribedClients(
+            PROP1,
+            val(VehicleAreaZone::ROW_2_LEFT),
+            SubscribeFlags::HAL_EVENT);
+    ASSERT_TRUE(clients.empty());
+
+    // Wrong prop
+    clients = manager.getSubscribedClients(
+            VehicleProperty::AP_POWER_BOOTUP_REASON,
+            val(VehicleAreaZone::ROW_1_LEFT),
+            SubscribeFlags::HAL_EVENT);
+    ASSERT_TRUE(clients.empty());
+
+    // Wrong flag
+    clients = manager.getSubscribedClients(
+            PROP1,
+            val(VehicleAreaZone::ROW_1_LEFT),
+            SubscribeFlags::SET_CALL);
+    ASSERT_TRUE(clients.empty());
+}
+
+TEST_F(SubscriptionManagerTest, mulipleSubscriptions) {
+    manager.addOrUpdateSubscription(cb1, subscrToProp1);
+
+    auto clients = manager.getSubscribedClients(
+            PROP1,
+            val(VehicleAreaZone::ROW_1_LEFT),
+            SubscribeFlags::DEFAULT);
+    ASSERT_EQ((size_t) 1, clients.size());
+    ASSERT_EQ(cb1, clients.front()->getCallback());
+
+    // Same property, but different zone, to make sure we didn't unsubscribe
+    // from previous zone.
+    manager.addOrUpdateSubscription(cb1, init_hidl_vec(
+        {
+            SubscribeOptions {
+                .propId = PROP1,
+                .vehicleAreas = val(VehicleAreaZone::ROW_2),
+                .flags = SubscribeFlags::DEFAULT
+            }
+        }));
+
+    clients = manager.getSubscribedClients(PROP1,
+                                           val(VehicleAreaZone::ROW_1_LEFT),
+                                           SubscribeFlags::DEFAULT);
+    ASSERT_ALL_EXISTS({cb1}, extractCallbacks(clients));
+
+    clients = manager.getSubscribedClients(PROP1,
+                                           val(VehicleAreaZone::ROW_2),
+                                           SubscribeFlags::DEFAULT);
+    ASSERT_ALL_EXISTS({cb1}, extractCallbacks(clients));
+}
+
+TEST_F(SubscriptionManagerTest, unsubscribe) {
+    manager.addOrUpdateSubscription(cb1, subscrToProp1);
+    manager.addOrUpdateSubscription(cb2, subscrToProp2);
+    manager.addOrUpdateSubscription(cb3, subscrToProp1and2);
+
+    ASSERT_ALL_EXISTS({cb1, cb3}, extractCallbacks(clientsToProp1()));
+    ASSERT_ALL_EXISTS({cb2, cb3}, extractCallbacks(clientsToProp2()));
+
+    ASSERT_FALSE(manager.unsubscribe(cb1, PROP1));
+    ASSERT_ALL_EXISTS({cb3}, extractCallbacks(clientsToProp1()));
+
+    // Make sure nothing changed in PROP2 so far.
+    ASSERT_ALL_EXISTS({cb2, cb3}, extractCallbacks(clientsToProp2()));
+
+    // No one subscribed to PROP1, subscription for PROP2 is not affected.
+    ASSERT_TRUE(manager.unsubscribe(cb3, PROP1));
+    ASSERT_ALL_EXISTS({cb2, cb3}, extractCallbacks(clientsToProp2()));
+
+    ASSERT_FALSE(manager.unsubscribe(cb3, PROP2));
+    ASSERT_ALL_EXISTS({cb2}, extractCallbacks(clientsToProp2()));
+
+    // The last client unsubscribed from this property.
+    ASSERT_TRUE(manager.unsubscribe(cb2, PROP2));
+
+    // No one was subscribed, return false.
+    ASSERT_FALSE(manager.unsubscribe(cb1, PROP1));
+}
+
+}  // namespace anonymous
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace hardware
+}  // namespace android
diff --git a/vehicle/2.0/default/tests/VehicleHalManager_test.cpp b/vehicle/2.0/default/tests/VehicleHalManager_test.cpp
new file mode 100644
index 0000000..1410ddf
--- /dev/null
+++ b/vehicle/2.0/default/tests/VehicleHalManager_test.cpp
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include <unordered_map>
+#include <iostream>
+
+#include <gtest/gtest.h>
+
+#include <vehicle_hal_manager/VehiclePropConfigIndex.h>
+#include <VehicleHal.h>
+#include <vehicle_hal_manager/VehicleHalManager.h>
+#include "vehicle_hal_manager/SubscriptionManager.h"
+
+#include "VehicleHalTestUtils.h"
+
+namespace android {
+namespace hardware {
+namespace vehicle {
+namespace V2_0 {
+
+namespace {
+
+using namespace std::placeholders;
+
+class MockedVehicleHal : public VehicleHal {
+public:
+    MockedVehicleHal() {
+        mConfigs.assign(std::begin(kVehicleProperties),
+                        std::end(kVehicleProperties));
+    }
+
+    std::vector<VehiclePropConfig> listProperties() override {
+        return mConfigs;
+    }
+
+    VehiclePropValuePtr get(VehicleProperty property,
+                 int32_t areaId,
+                 status_t* outStatus) override {
+        *outStatus = OK;
+        return getValuePool()->obtain(mValues[property]);
+    }
+
+    status_t set(const VehiclePropValue& propValue) override {
+        mValues[propValue.prop] = propValue;
+        return OK;
+    }
+
+    status_t subscribe(VehicleProperty property,
+                       int32_t areas,
+                       float sampleRate) override {
+        return OK;
+    }
+
+    status_t unsubscribe(VehicleProperty property) override {
+        return OK;
+    }
+
+    void sendPropEvent(recyclable_ptr<VehiclePropValue> value) {
+        doHalEvent(std::move(value));
+    }
+
+private:
+    std::vector<VehiclePropConfig> mConfigs;
+    std::unordered_map<VehicleProperty, VehiclePropValue> mValues;
+};
+
+class VehicleHalManagerTest : public ::testing::Test {
+protected:
+    void SetUp() override {
+        hal.reset(new MockedVehicleHal);
+        manager.reset(new VehicleHalManager(hal.get()));
+
+        objectPool = hal->getValuePool();
+    }
+
+    void TearDown() override {
+        manager.reset(nullptr);
+        hal.reset(nullptr);
+    }
+
+public:
+    VehiclePropValuePool* objectPool;
+    std::unique_ptr<MockedVehicleHal> hal;
+    std::unique_ptr<VehicleHalManager> manager;
+};
+
+class HalClientVectorTest : public ::testing::Test {
+public:
+    HalClientVector clients;
+};
+
+TEST_F(VehicleHalManagerTest, getPropConfigs) {
+    hidl_vec<VehicleProperty> properties = init_hidl_vec(
+        { VehicleProperty::HVAC_FAN_SPEED,VehicleProperty::INFO_MAKE} );
+    bool called = false;
+    manager->getPropConfigs(properties,
+                            [&called] (const hidl_vec<VehiclePropConfig>& c) {
+        ASSERT_EQ(2u, c.size());
+        called = true;
+    });
+    ASSERT_TRUE(called);  // Verify callback received.
+
+    called = false;
+    manager->getPropConfigs(init_hidl_vec({VehicleProperty::HVAC_FAN_SPEED}),
+                            [&called] (const hidl_vec<VehiclePropConfig>& c) {
+        ASSERT_EQ(1u, c.size());
+        ASSERT_EQ(toString(kVehicleProperties[1]), toString(c[0]));
+        called = true;
+    });
+    ASSERT_TRUE(called);  // Verify callback received.
+}
+
+TEST_F(VehicleHalManagerTest, getAllPropConfigs) {
+    bool called = false;
+    manager->getAllPropConfigs(
+            [&called] (const hidl_vec<VehiclePropConfig>& propConfigs) {
+        ASSERT_EQ(arraysize(kVehicleProperties), propConfigs.size());
+
+        for (size_t i = 0; i < propConfigs.size(); i++) {
+            ASSERT_EQ(toString(kVehicleProperties[i]),
+                      toString(propConfigs[i]));
+        }
+        called = true;
+    });
+    ASSERT_TRUE(called);  // Verify callback received.
+}
+
+TEST_F(VehicleHalManagerTest, subscribe) {
+    const VehicleProperty PROP = VehicleProperty::DISPLAY_BRIGHTNESS;
+
+    sp<MockedVehicleCallback> cb = new MockedVehicleCallback();
+
+    hidl_vec<SubscribeOptions> options = init_hidl_vec(
+        {
+            SubscribeOptions {
+                .propId = PROP,
+                .flags = SubscribeFlags::DEFAULT
+            },
+        });
+
+    StatusCode res = manager->subscribe(cb, options);
+    ASSERT_EQ(StatusCode::OK, res);
+
+    auto unsubscribedValue = objectPool->obtain(VehiclePropertyType::INT32);
+    unsubscribedValue->prop = VehicleProperty::HVAC_FAN_SPEED;
+
+    hal->sendPropEvent(std::move(unsubscribedValue));
+    auto& receivedEnvents = cb->getReceivedEvents();
+
+    ASSERT_TRUE(cb->waitForExpectedEvents(0)) << " Unexpected events received: "
+              << receivedEnvents.size()
+              << (receivedEnvents.size() > 0
+                      ? toString(receivedEnvents.front()[0]) : "");
+
+    auto subscribedValue = objectPool->obtain(VehiclePropertyType::INT32);
+    subscribedValue->prop = PROP;
+    subscribedValue->value.int32Values[0] = 42;
+
+    cb->reset();
+    VehiclePropValue actualValue(*subscribedValue.get());
+    hal->sendPropEvent(std::move(subscribedValue));
+
+    ASSERT_TRUE(cb->waitForExpectedEvents(1)) << "Events received: "
+            << receivedEnvents.size();
+
+    ASSERT_EQ(toString(actualValue),
+              toString(cb->getReceivedEvents().front()[0]));
+}
+
+TEST_F(HalClientVectorTest, basic) {
+    sp<IVehicleCallback> callback1 = new MockedVehicleCallback();
+
+    sp<HalClient> c1 = new HalClient(callback1, 10, 20);
+    sp<HalClient> c2 = new HalClient(callback1, 10, 20);
+
+    clients.addOrUpdate(c1);
+    clients.addOrUpdate(c1);
+    clients.addOrUpdate(c2);
+    ASSERT_EQ(2u, clients.size());
+    ASSERT_FALSE(clients.isEmpty());
+    ASSERT_GE(0, clients.indexOf(c1));
+    ASSERT_GE(0, clients.remove(c1));
+    ASSERT_GE(0, clients.indexOf(c1));
+    ASSERT_GE(0, clients.remove(c1));
+    ASSERT_GE(0, clients.remove(c2));
+
+    ASSERT_TRUE(clients.isEmpty());
+}
+
+}  // namespace anonymous
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace hardware
+}  // namespace android
diff --git a/vehicle/2.0/default/tests/VehicleHalTestUtils.h b/vehicle/2.0/default/tests/VehicleHalTestUtils.h
new file mode 100644
index 0000000..b3b3ffa
--- /dev/null
+++ b/vehicle/2.0/default/tests/VehicleHalTestUtils.h
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2016 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 android_hardware_vehicle_V2_0_VehicleDebugUtils_H_
+#define android_hardware_vehicle_V2_0_VehicleDebugUtils_H_
+
+#include <android/hardware/vehicle/2.0/types.h>
+#include <vehicle_hal_manager/VehicleUtils.h>
+#include <ios>
+#include <sstream>
+
+namespace android {
+namespace hardware {
+namespace vehicle {
+namespace V2_0 {
+
+const VehiclePropConfig kVehicleProperties[] = {
+    {
+        .prop = VehicleProperty::INFO_MAKE,
+        .access = VehiclePropertyAccess::READ,
+        .changeMode = VehiclePropertyChangeMode::STATIC,
+        .permissionModel = VehiclePermissionModel::OEM_ONLY,
+        .configString = "Some=config,options=if,you=have_any",
+    },
+
+    {
+        .prop = VehicleProperty::HVAC_FAN_SPEED,
+        .access = VehiclePropertyAccess::READ_WRITE,
+        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+        .permissionModel = VehiclePermissionModel::NO_RESTRICTION,
+        .supportedAreas = static_cast<int32_t>(
+            VehicleAreaZone::ROW_1_LEFT | VehicleAreaZone::ROW_1_RIGHT),
+        .areaConfigs = init_hidl_vec({
+                                         VehicleAreaConfig {
+                                             .areaId = val(
+                                                 VehicleAreaZone::ROW_2_LEFT),
+                                             .minInt32Value = 1,
+                                             .maxInt32Value = 7},
+                                         VehicleAreaConfig {
+                                             .areaId = val(
+                                                 VehicleAreaZone::ROW_1_RIGHT),
+                                             .minInt32Value = 1,
+                                             .maxInt32Value = 5,
+                                         }
+                                     }),
+    },
+
+    {
+        .prop = VehicleProperty::INFO_FUEL_CAPACITY,
+        .access = VehiclePropertyAccess::READ,
+        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+        .permissionModel = VehiclePermissionModel::OEM_ONLY,
+        .areaConfigs = init_hidl_vec({
+                                         VehicleAreaConfig {
+                                             .minFloatValue = 0,
+                                             .maxFloatValue = 1.0
+                                         }
+                                     })
+    },
+
+    {
+        .prop = VehicleProperty::DISPLAY_BRIGHTNESS,
+        .access = VehiclePropertyAccess::READ_WRITE,
+        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+        .permissionModel = VehiclePermissionModel::OEM_ONLY,
+        .areaConfigs = init_hidl_vec({
+                                         VehicleAreaConfig {
+                                             .minInt32Value = 0,
+                                             .maxInt32Value = 10
+                                         }
+                                     })
+    }
+};
+
+constexpr auto kTimeout = std::chrono::milliseconds(500);
+
+class MockedVehicleCallback : public IVehicleCallback {
+public:
+    // Methods from ::android::hardware::vehicle::V2_0::IVehicleCallback follow.
+    Return<void> onPropertyEvent(
+            const hidl_vec<VehiclePropValue>& values) override {
+        {
+            MuxGuard  g(mLock);
+            mReceivedEvents.push_back(values);
+        }
+        mEventCond.notify_one();
+        return Return<void>();
+    }
+    Return<void> onPropertySet(const VehiclePropValue& value) override {
+        return Return<void>();
+    }
+    Return<void> onError(StatusCode errorCode,
+                         VehicleProperty propId,
+                         VehiclePropertyOperation operation) override {
+        return Return<void>();
+    }
+
+    bool waitForExpectedEvents(size_t expectedEvents) {
+        std::unique_lock<std::mutex> g(mLock);
+
+        if (expectedEvents == 0 && mReceivedEvents.size() == 0) {
+            // No events expected, let's sleep a little bit to make sure
+            // nothing will show up.
+            return mEventCond.wait_for(g, kTimeout) == std::cv_status::timeout;
+        }
+
+        while (expectedEvents != mReceivedEvents.size()) {
+            if (mEventCond.wait_for(g, kTimeout) == std::cv_status::timeout) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    void reset() {
+        mReceivedEvents.clear();
+    }
+
+    const std::vector<hidl_vec<VehiclePropValue>>& getReceivedEvents() {
+        return mReceivedEvents;
+    }
+
+private:
+    using MuxGuard = std::lock_guard<std::mutex>;
+
+    std::mutex mLock;
+    std::condition_variable mEventCond;
+    std::vector<hidl_vec<VehiclePropValue>> mReceivedEvents;
+};
+
+template<typename T>
+inline std::string hexString(T value) {
+    std::stringstream ss;
+    ss << std::showbase << std::hex << value;
+    return ss.str();
+}
+
+template <typename T, typename Collection>
+inline void assertAllExistsAnyOrder(
+        std::initializer_list<T> expected,
+        const Collection& actual,
+        const char* msg) {
+    std::set<T> expectedSet = expected;
+
+    for (auto a: actual) {
+        ASSERT_EQ(1u, expectedSet.erase(a))
+                << msg << "\nContains not unexpected value.\n";
+    }
+
+    ASSERT_EQ(0u, expectedSet.size())
+            << msg
+            << "\nDoesn't contain expected value.";
+}
+
+#define ASSERT_ALL_EXISTS(...) \
+    assertAllExistsAnyOrder(__VA_ARGS__, (std::string("Called from: ") + \
+            std::string(__FILE__) + std::string(":") + \
+            std::to_string(__LINE__)).c_str()); \
+
+template<typename T>
+inline std::string enumToHexString(T value) {
+    return hexString(val(value));
+}
+
+template <typename T>
+inline std::string toString(const hidl_vec<T>& vec) {
+    std::stringstream ss("[");
+    for (size_t i = 0; i < vec.size(); i++) {
+        if (i != 0) ss << ",";
+        ss << vec[i];
+    }
+    ss << "]";
+    return ss.str();
+}
+
+inline std::string toString(const VehiclePropValue &v) {
+    std::stringstream ss;
+    ss << "VehiclePropValue {n"
+       << "  prop: " << enumToHexString(v.prop) << ",\n"
+       << "  areaId: " << hexString(v.areaId) << ",\n"
+       << "  timestamp: " << v.timestamp << ",\n"
+       << "  value {\n"
+       << "    int32Values: " << toString(v.value.int32Values) << ",\n"
+       << "    floatValues: " << toString(v.value.floatValues) << ",\n"
+       << "    int64Values: " << toString(v.value.int64Values) << ",\n"
+       << "    bytes: " << toString(v.value.bytes) << ",\n"
+       << "    string: " << v.value.stringValue.c_str() << ",\n"
+       << "  }\n"
+       << "}\n";
+
+    return ss.str();
+}
+
+inline std::string toString(const VehiclePropConfig &config) {
+    std::stringstream ss;
+    ss << "VehiclePropConfig {\n"
+       << "  prop: " << enumToHexString(config.prop) << ",\n"
+       << "  supportedAreas: " << hexString(config.supportedAreas) << ",\n"
+       << "  access: " << enumToHexString(config.access) << ",\n"
+       << "  permissionModel: " << enumToHexString(config.permissionModel) << ",\n"
+       << "  changeMode: " << enumToHexString(config.changeMode) << ",\n"
+       << "  configFlags: " << hexString(config.configFlags) << ",\n"
+       << "  minSampleRate: " << config.minSampleRate << ",\n"
+       << "  maxSampleRate: " << config.maxSampleRate << ",\n"
+       << "  configString: " << config.configString.c_str() << ",\n";
+
+    ss << "  areaConfigs {\n";
+    for (size_t i = 0; i < config.areaConfigs.size(); i++) {
+        const auto &area = config.areaConfigs[i];
+        ss << "    areaId: " << hexString(area.areaId) << ",\n"
+           << "    minFloatValue: " << area.minFloatValue << ",\n"
+           << "    minFloatValue: " << area.maxFloatValue << ",\n"
+           << "    minInt32Value: " << area.minInt32Value << ",\n"
+           << "    minInt32Value: " << area.maxInt32Value << ",\n"
+           << "    minInt64Value: " << area.minInt64Value << ",\n"
+           << "    minInt64Value: " << area.maxInt64Value << ",\n";
+    }
+    ss << "  }\n"
+       << "}\n";
+
+    return ss.str();
+}
+
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace hardware
+}  // namespace android
+
+
+#endif //VEHICLEHALDEBUGUTILS_H
diff --git a/vehicle/2.0/default/tests/VehicleObjectPool_test.cpp b/vehicle/2.0/default/tests/VehicleObjectPool_test.cpp
new file mode 100644
index 0000000..88b1be0
--- /dev/null
+++ b/vehicle/2.0/default/tests/VehicleObjectPool_test.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include <thread>
+
+#include <gtest/gtest.h>
+
+#include <vehicle_hal_manager/VehicleObjectPool.h>
+#include <utils/SystemClock.h>
+
+namespace android {
+namespace hardware {
+namespace vehicle {
+namespace V2_0 {
+
+namespace {
+
+class VehicleObjectPoolTest : public ::testing::Test {
+protected:
+    void SetUp() override {
+        stats = PoolStats::instance();
+        resetStats();
+        valuePool.reset(new VehiclePropValuePool);
+    }
+
+    void TearDown() override {
+        // At the end, all created objects should be either recycled or deleted.
+        // Some objects could be recycled multiple times, that's why it's <=
+        ASSERT_EQ(stats->Obtained, stats->Recycled);
+        ASSERT_LE(stats->Created, stats->Recycled);
+    }
+private:
+    void resetStats() {
+        stats->Obtained = 0;
+        stats->Created = 0;
+        stats->Recycled = 0;
+    }
+
+public:
+    PoolStats* stats;
+    std::unique_ptr<VehiclePropValuePool> valuePool;
+};
+
+TEST_F(VehicleObjectPoolTest, valuePoolBasicCorrectness) {
+    void* raw = valuePool->obtain(VehiclePropertyType::INT32).get();
+    // At this point, v1 should be recycled and the only object in the pool.
+    ASSERT_EQ(raw, valuePool->obtain(VehiclePropertyType::INT32).get());
+    // Obtaining value of another type - should return a new object
+    ASSERT_NE(raw, valuePool->obtain(VehiclePropertyType::FLOAT).get());
+
+    ASSERT_EQ(3u, stats->Obtained);
+    ASSERT_EQ(2u, stats->Created);
+}
+
+TEST_F(VehicleObjectPoolTest, valuePoolStrings) {
+    valuePool->obtain(VehiclePropertyType::STRING);
+    auto vs = valuePool->obtain(VehiclePropertyType::STRING);
+    vs->value.stringValue = "Hello";
+    void* raw = vs.get();
+    vs.reset();  // delete the pointer
+
+    auto vs2 = valuePool->obtain(VehiclePropertyType::STRING);
+    ASSERT_EQ(0u, vs2->value.stringValue.size());
+    ASSERT_NE(raw, valuePool->obtain(VehiclePropertyType::STRING).get());
+
+    ASSERT_EQ(0u, stats->Obtained);
+}
+
+TEST_F(VehicleObjectPoolTest, valuePoolMultithreadedBenchmark) {
+    // In this test we have T threads that concurrently in C cycles
+    // obtain and release O VehiclePropValue objects of FLOAT / INT32 types.
+
+    const auto T = 2;
+    const auto C  = 500;
+    const auto O = 100;
+
+    auto poolPtr = valuePool.get();
+
+    std::vector<std::thread> threads;
+    auto start = elapsedRealtimeNano();
+    for (int i = 0; i < T; i++) {
+        threads.push_back(std::thread([&poolPtr] () {
+            for (int j = 0; j < C; j++) {
+                std::vector<recyclable_ptr<VehiclePropValue>> vec;
+                for (int k = 0; k < O; k++) {
+                    vec.push_back(
+                        poolPtr->obtain(k % 2 == 0
+                                        ? VehiclePropertyType::FLOAT
+                                        : VehiclePropertyType::INT32));
+                }
+            }
+        }));
+    }
+
+    for (auto& t : threads) {
+        t.join();
+    }
+    auto finish = elapsedRealtimeNano();
+
+    ASSERT_EQ(T * C * O, stats->Obtained);
+    ASSERT_EQ(T * C * O, stats->Recycled);
+    // Created less than obtained.
+    ASSERT_GE(T * O, stats->Created);
+
+    auto elapsedMs = (finish - start) / 1000000;
+    ASSERT_GE(1000, elapsedMs);  // Less a second to access 100K objects.
+                                 // Typically it takes about 0.1s on Nexus6P.
+}
+
+}  // namespace anonymous
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace hardware
+}  // namespace android
diff --git a/vehicle/2.0/default/tests/VehiclePropConfigIndex_test.cpp b/vehicle/2.0/default/tests/VehiclePropConfigIndex_test.cpp
new file mode 100644
index 0000000..aae7e62
--- /dev/null
+++ b/vehicle/2.0/default/tests/VehiclePropConfigIndex_test.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include <gtest/gtest.h>
+
+#include <vehicle_hal_manager/VehiclePropConfigIndex.h>
+
+#include "VehicleHalTestUtils.h"
+
+namespace android {
+namespace hardware {
+namespace vehicle {
+namespace V2_0 {
+
+namespace {
+
+class PropConfigTest : public ::testing::Test {
+protected:
+    void SetUp() override {
+        configs.assign(std::begin(kVehicleProperties),
+                       std::end(kVehicleProperties));
+    }
+
+    void TearDown() override {}
+
+public:
+    std::vector<VehiclePropConfig> configs;
+};
+
+TEST_F(PropConfigTest, hasConfig) {
+    VehiclePropConfigIndex index(configs);
+
+    ASSERT_TRUE(index.hasConfig(VehicleProperty::HVAC_FAN_SPEED));
+    ASSERT_TRUE(index.hasConfig(VehicleProperty::INFO_MAKE));
+    ASSERT_TRUE(index.hasConfig(VehicleProperty::INFO_FUEL_CAPACITY));
+
+    ASSERT_FALSE(index.hasConfig(VehicleProperty::INVALID));
+}
+
+TEST_F(PropConfigTest, getAllConfig) {
+    VehiclePropConfigIndex index(configs);
+
+    std::vector<VehiclePropConfig> actualConfigs = index.getAllConfigs();
+    ASSERT_EQ(configs.size(), actualConfigs.size());
+
+    for (size_t i = 0; i < actualConfigs.size(); i++) {
+        ASSERT_EQ(toString(configs[i]), toString(actualConfigs[i]));
+    }
+}
+
+TEST_F(PropConfigTest, getConfigs) {
+    VehiclePropConfigIndex index(configs);
+    auto actualConfig = index.getConfig(VehicleProperty::HVAC_FAN_SPEED);
+    ASSERT_EQ(toString(configs[1]), toString(actualConfig));
+}
+
+}  // namespace anonymous
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace hardware
+}  // namespace android
\ No newline at end of file
diff --git a/vehicle/2.0/default/vehicle_hal_manager/ConcurrentQueue.h b/vehicle/2.0/default/vehicle_hal_manager/ConcurrentQueue.h
new file mode 100644
index 0000000..a64ef46
--- /dev/null
+++ b/vehicle/2.0/default/vehicle_hal_manager/ConcurrentQueue.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2016 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 android_hardware_vehicle_V2_0_ConcurrentQueue_H_
+#define android_hardware_vehicle_V2_0_ConcurrentQueue_H_
+
+#include <queue>
+#include <atomic>
+#include <thread>
+#include <condition_variable>
+#include <iostream>
+
+namespace android {
+
+template<typename T>
+class ConcurrentQueue {
+public:
+    void waitForItems() {
+        std::unique_lock<std::mutex> g(mLock);
+        while (mQueue.empty() && mIsActive) {
+            mCond.wait(g);
+        }
+    }
+
+    std::vector<T> flush() {
+        std::vector<T> items;
+
+        MuxGuard g(mLock);
+        if (mQueue.empty() || !mIsActive) {
+            return items;
+        }
+        while (!mQueue.empty()) {
+            items.push_back(std::move(mQueue.front()));
+            mQueue.pop();
+        }
+        return items;
+    }
+
+    void push(T&& item) {
+        {
+            MuxGuard g(mLock);
+            if (!mIsActive) {
+                return;
+            }
+            mQueue.push(std::move(item));
+        }
+        mCond.notify_one();
+    }
+
+    /* Deactivates the queue, thus no one can push items to it, also
+     * notifies all waiting thread.
+     */
+    void deactivate() {
+        {
+            MuxGuard g(mLock);
+            mIsActive = false;
+        }
+        mCond.notify_all();  // To unblock all waiting consumers.
+    }
+
+    ConcurrentQueue() = default;
+
+    ConcurrentQueue(const ConcurrentQueue &) = delete;
+    ConcurrentQueue &operator=(const ConcurrentQueue &) = delete;
+private:
+    using MuxGuard = std::lock_guard<std::mutex>;
+
+    bool mIsActive = true;
+    mutable std::mutex mLock;
+    std::condition_variable mCond;
+    std::queue<T> mQueue;
+};
+
+template<typename T>
+class BatchingConsumer {
+private:
+    enum class State {
+        INIT = 0,
+        RUNNING = 1,
+        STOP_REQUESTED = 2,
+        STOPPED = 3,
+    };
+
+public:
+    BatchingConsumer() : mState(State::INIT) {}
+
+    BatchingConsumer(const BatchingConsumer &) = delete;
+    BatchingConsumer &operator=(const BatchingConsumer &) = delete;
+
+    using OnBatchReceivedFunc = std::function<void(const std::vector<T>& vec)>;
+
+    void run(ConcurrentQueue<T>* queue,
+             std::chrono::nanoseconds batchInterval,
+             const OnBatchReceivedFunc& func) {
+        mQueue = queue;
+        mBatchInterval = batchInterval;
+
+        std::thread(&BatchingConsumer<T>::runInternal, this, func).detach();
+    }
+
+    void requestStop() {
+        if (mState.exchange(State::STOP_REQUESTED) != State::RUNNING) {
+              mState = State::STOPPED;
+          }
+    }
+
+    void waitStopped() {
+        std::unique_lock<std::mutex> g(mLock);
+        while (State::STOPPED != mState) {
+            mCondStopped.wait_for(g, std::chrono::seconds(1));
+        }
+    }
+
+private:
+    void runInternal(const OnBatchReceivedFunc& onBatchReceived) {
+        if (mState.exchange(State::RUNNING) == State::INIT) {
+            while (State::RUNNING == mState) {
+                mQueue->waitForItems();
+                if (State::STOP_REQUESTED == mState) break;
+
+                std::this_thread::sleep_for(mBatchInterval);
+                if (State::STOP_REQUESTED == mState) break;
+
+                std::vector<T> items = mQueue->flush();
+
+                if (items.size() > 0) {
+                    onBatchReceived(items);
+                }
+            }
+        }
+
+        mState = State::STOPPED;
+        mCondStopped.notify_one();
+    }
+
+private:
+    std::mutex mLock;
+    std::condition_variable mCondStopped;
+
+    std::atomic<State> mState;
+    std::chrono::nanoseconds mBatchInterval;
+    ConcurrentQueue<T>* mQueue;
+};
+
+}  // namespace android
+
+#endif //android_hardware_vehicle_V2_0_ConcurrentQueue_H_
diff --git a/vehicle/2.0/default/vehicle_hal_manager/SubscriptionManager.cpp b/vehicle/2.0/default/vehicle_hal_manager/SubscriptionManager.cpp
new file mode 100644
index 0000000..0d2180f
--- /dev/null
+++ b/vehicle/2.0/default/vehicle_hal_manager/SubscriptionManager.cpp
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#define LOG_TAG "android.hardware.vehicle@2.0-impl"
+
+#include <cmath>
+
+#include <utils/Errors.h>
+
+#include "VehicleUtils.h"
+#include "SubscriptionManager.h"
+
+namespace android {
+namespace hardware {
+namespace vehicle {
+namespace V2_0 {
+
+bool mergeSubscribeOptions(const SubscribeOptions &oldOpts,
+                           const SubscribeOptions &newOpts,
+                           SubscribeOptions *outResult) {
+
+    int32_t updatedAreas = oldOpts.vehicleAreas;
+    if (updatedAreas != kAllSupportedAreas) {
+        updatedAreas = newOpts.vehicleAreas != kAllSupportedAreas
+            ? updatedAreas | newOpts.vehicleAreas
+            : kAllSupportedAreas;
+    }
+
+    float updatedRate = std::max(oldOpts.sampleRate, newOpts.sampleRate);
+    SubscribeFlags updatedFlags = oldOpts.flags | newOpts.flags;
+
+    bool updated = updatedRate > oldOpts.sampleRate
+                   || updatedAreas != oldOpts.vehicleAreas
+                   || updatedFlags != oldOpts.flags;
+    if (updated) {
+        *outResult = oldOpts;
+        outResult->vehicleAreas = updatedAreas;
+        outResult->sampleRate = updatedRate;
+        outResult->flags = updatedFlags;
+    }
+
+    return updated;
+}
+
+void HalClient::addOrUpdateSubscription(const SubscribeOptions &opts)  {
+    auto it = mSubscriptions.find(opts.propId);
+    if (it == mSubscriptions.end()) {
+        mSubscriptions.emplace(opts.propId, opts);
+    } else {
+        const SubscribeOptions& oldOpts = it->second;
+        SubscribeOptions updatedOptions;
+        if (mergeSubscribeOptions(oldOpts, opts, &updatedOptions)) {
+            mSubscriptions.erase(it);
+            mSubscriptions.emplace(opts.propId, updatedOptions);
+        }
+    }
+}
+
+bool HalClient::isSubscribed(VehicleProperty propId, int32_t areaId, SubscribeFlags flags) {
+    auto it = mSubscriptions.find(propId);
+    if (it == mSubscriptions.end()) {
+        return false;
+    }
+    const SubscribeOptions& opts = it->second;
+    bool res = (opts.flags & flags)
+           && (opts.vehicleAreas == 0 || areaId == 0 || opts.vehicleAreas & areaId);
+    return res;
+}
+
+std::list<SubscribeOptions> SubscriptionManager::addOrUpdateSubscription(
+        const sp<IVehicleCallback> &callback,
+        const hidl_vec<SubscribeOptions> &optionList) {
+    std::list<SubscribeOptions> updatedSubscriptions;
+
+    MuxGuard g(mLock);
+
+    const sp<HalClient>& client = getOrCreateHalClientLocked(callback);
+
+    for (size_t i = 0; i < optionList.size(); i++) {
+        const SubscribeOptions& opts = optionList[i];
+        client->addOrUpdateSubscription(opts);
+
+        addClientToPropMapLocked(opts.propId, client);
+
+        if (SubscribeFlags::HAL_EVENT & opts.flags) {
+            SubscribeOptions updated;
+            if (updateHalEventSubscriptionLocked(opts, &updated)) {
+                updatedSubscriptions.push_back(updated);
+            }
+        }
+    }
+
+    return updatedSubscriptions;
+}
+
+std::list<HalClientValues> SubscriptionManager::distributeValuesToClients(
+        const std::vector<recyclable_ptr<VehiclePropValue>>& propValues,
+        SubscribeFlags flags) const {
+    std::map<sp<HalClient>, std::list<VehiclePropValue*>> clientValuesMap;
+
+    {
+        MuxGuard g(mLock);
+        for (const auto& propValue: propValues) {
+            VehiclePropValue* v = propValue.get();
+            auto clients = getSubscribedClientsLocked(
+                v->prop, v->areaId, flags);
+            for (const auto& client : clients) {
+                clientValuesMap[client].push_back(v);
+            }
+        }
+    }
+
+    std::list<HalClientValues> clientValues;
+    for (const auto& entry : clientValuesMap) {
+        clientValues.push_back(HalClientValues {
+            .client = entry.first,
+            .values = entry.second
+        });
+    }
+
+    return clientValues;
+}
+
+std::list<sp<HalClient>> SubscriptionManager::getSubscribedClients(
+    VehicleProperty propId, int32_t area, SubscribeFlags flags) const {
+    MuxGuard g(mLock);
+    return getSubscribedClientsLocked(propId, area, flags);
+}
+
+std::list<sp<HalClient>> SubscriptionManager::getSubscribedClientsLocked(
+        VehicleProperty propId, int32_t area, SubscribeFlags flags) const {
+    std::list<sp<HalClient>> subscribedClients;
+
+    sp<HalClientVector> propClients = getClientsForPropertyLocked(propId);
+    if (propClients.get() != nullptr) {
+        for (size_t i = 0; i < propClients->size(); i++) {
+            const auto& client = propClients->itemAt(i);
+            if (client->isSubscribed(propId, area, flags)) {
+                subscribedClients.push_back(client);
+            }
+        }
+    }
+
+    return subscribedClients;
+}
+
+bool SubscriptionManager::updateHalEventSubscriptionLocked(
+        const SubscribeOptions &opts, SubscribeOptions *outUpdated) {
+    bool updated = false;
+    auto it = mHalEventSubscribeOptions.find(opts.propId);
+    if (it == mHalEventSubscribeOptions.end()) {
+        *outUpdated = opts;
+        mHalEventSubscribeOptions.emplace(opts.propId, opts);
+        updated = true;
+    } else {
+        const SubscribeOptions& oldOpts = it->second;
+
+        if (mergeSubscribeOptions(oldOpts, opts, outUpdated)) {
+            mHalEventSubscribeOptions.erase(opts.propId);
+            mHalEventSubscribeOptions.emplace(opts.propId, *outUpdated);
+            updated = true;
+        }
+    }
+
+    return updated;
+}
+
+void SubscriptionManager::addClientToPropMapLocked(
+        VehicleProperty propId, const sp<HalClient> &client) {
+    auto it = mPropToClients.find(propId);
+    sp<HalClientVector> propClients;
+    if (it == mPropToClients.end()) {
+        propClients = new HalClientVector();
+        mPropToClients.insert(std::make_pair(propId, propClients));
+    } else {
+        propClients = it->second;
+    }
+    propClients->addOrUpdate(client);
+}
+
+sp<HalClientVector> SubscriptionManager::getClientsForPropertyLocked(
+        VehicleProperty propId) const {
+    auto it = mPropToClients.find(propId);
+    return it == mPropToClients.end() ? nullptr : it->second;
+}
+
+sp<HalClient> SubscriptionManager::getOrCreateHalClientLocked(
+        const sp<IVehicleCallback>& callback) {
+    auto it = mClients.find(callback);
+    if (it == mClients.end()) {
+        IPCThreadState* self = IPCThreadState::self();
+        pid_t pid = self->getCallingPid();
+        uid_t uid = self->getCallingUid();
+        sp<HalClient> client = new HalClient(callback, pid, uid);
+        mClients.emplace(callback, client);
+        return client;
+    } else {
+        return it->second;
+    }
+}
+
+bool SubscriptionManager::unsubscribe(const sp<IVehicleCallback>& callback,
+                                      VehicleProperty propId) {
+    MuxGuard g(mLock);
+    auto propertyClients = getClientsForPropertyLocked(propId);
+    auto clientIter = mClients.find(callback);
+    if (clientIter == mClients.end()) {
+        ALOGW("Unable to unsubscribe: no callback found, propId: 0x%x", propId);
+    } else {
+        auto client = clientIter->second;
+
+        if (propertyClients != nullptr) {
+            propertyClients->remove(client);
+
+            if (propertyClients->isEmpty()) {
+                mPropToClients.erase(propId);
+            }
+        }
+
+        bool isClientSubscribedToOtherProps = false;
+        for (const auto& propClient : mPropToClients) {
+            if (propClient.second->indexOf(client) >= 0) {
+                isClientSubscribedToOtherProps = true;
+                break;
+            }
+        }
+
+        if (!isClientSubscribedToOtherProps) {
+            mClients.erase(clientIter);
+        }
+    }
+
+    return (propertyClients == nullptr || propertyClients->isEmpty())
+            ? mHalEventSubscribeOptions.erase(propId) == 1
+            : false;
+}
+
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace hardware
+}  // namespace android
diff --git a/vehicle/2.0/default/vehicle_hal_manager/SubscriptionManager.h b/vehicle/2.0/default/vehicle_hal_manager/SubscriptionManager.h
new file mode 100644
index 0000000..903bde5
--- /dev/null
+++ b/vehicle/2.0/default/vehicle_hal_manager/SubscriptionManager.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2016 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 android_hardware_vehicle_V2_0_SubscriptionManager_H_
+#define android_hardware_vehicle_V2_0_SubscriptionManager_H_
+
+#include <memory>
+#include <map>
+#include <set>
+#include <list>
+
+#include <utils/Log.h>
+#include <hwbinder/IPCThreadState.h>
+
+#include <android/hardware/vehicle/2.0/IVehicle.h>
+
+#include "ConcurrentQueue.h"
+#include "VehicleObjectPool.h"
+
+namespace android {
+namespace hardware {
+namespace vehicle {
+namespace V2_0 {
+
+class HalClient : public android::RefBase {
+public:
+    HalClient(const sp<IVehicleCallback> &callback,
+              int32_t pid,
+              int32_t uid)
+        : mCallback(callback), mPid(pid), mUid(uid) {}
+
+    virtual ~HalClient() {}
+public:
+    sp<IVehicleCallback> getCallback() const {
+        return mCallback;
+    }
+
+    void addOrUpdateSubscription(const SubscribeOptions &opts);
+
+    bool isSubscribed(VehicleProperty propId,
+                      int32_t areaId,
+                      SubscribeFlags flags);
+
+private:
+    const sp<IVehicleCallback> mCallback;
+    const int32_t mPid;
+    const int32_t mUid;
+
+    std::map<VehicleProperty, SubscribeOptions> mSubscriptions;
+};
+
+class HalClientVector : private SortedVector<sp<HalClient>> , public RefBase {
+public:
+    virtual ~HalClientVector() {}
+
+    inline void addOrUpdate(const sp<HalClient> &client) {
+        SortedVector::add(client);
+    }
+
+    using SortedVector::remove;
+    using SortedVector::size;
+    using SortedVector::indexOf;
+    using SortedVector::itemAt;
+    using SortedVector::isEmpty;
+};
+
+struct HalClientValues {
+    sp<HalClient> client;
+    std::list<VehiclePropValue *> values;
+};
+
+class SubscriptionManager {
+public:
+    virtual ~SubscriptionManager() {}
+
+    /**
+     * Updates subscription. Returns the vector of properties subscription that
+     * needs to be updated in VehicleHAL.
+     */
+    std::list<SubscribeOptions> addOrUpdateSubscription(
+            const sp<IVehicleCallback>& callback,
+            const hidl_vec<SubscribeOptions>& optionList);
+
+    /**
+     * Returns a list of IVehicleCallback -> list of VehiclePropValue ready for
+     * dispatching to its clients.
+     */
+    std::list<HalClientValues> distributeValuesToClients(
+            const std::vector<recyclable_ptr<VehiclePropValue>>& propValues,
+            SubscribeFlags flags) const;
+
+    std::list<sp<HalClient>> getSubscribedClients(
+        VehicleProperty propId, int32_t area, SubscribeFlags flags) const;
+
+    /**
+     * Returns true the client was unsubscribed successfully and there are
+     * no more clients subscribed to given propId.
+     */
+    bool unsubscribe(const sp<IVehicleCallback>& callback,
+                     VehicleProperty propId);
+private:
+    std::list<sp< HalClient>> getSubscribedClientsLocked(
+            VehicleProperty propId, int32_t area, SubscribeFlags flags) const;
+
+    bool updateHalEventSubscriptionLocked(const SubscribeOptions &opts,
+                                          SubscribeOptions *out);
+
+    void addClientToPropMapLocked(VehicleProperty propId,
+                                  const sp<HalClient> &client);
+
+    sp<HalClientVector> getClientsForPropertyLocked(
+            VehicleProperty propId) const;
+
+    sp<HalClient> getOrCreateHalClientLocked(
+            const sp<IVehicleCallback> &callback);
+
+private:
+    using MuxGuard = std::lock_guard<std::mutex>;
+
+    mutable std::mutex mLock;
+
+    std::map<sp<IVehicleCallback>, sp<HalClient>> mClients;
+    std::map<VehicleProperty, sp<HalClientVector>> mPropToClients;
+    std::map<VehicleProperty, SubscribeOptions> mHalEventSubscribeOptions;
+};
+
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace hardware
+}  // namespace android
+
+
+#endif // android_hardware_vehicle_V2_0_SubscriptionManager_H_
diff --git a/vehicle/2.0/default/VehicleCallback.cpp b/vehicle/2.0/default/vehicle_hal_manager/VehicleCallback.cpp
similarity index 100%
rename from vehicle/2.0/default/VehicleCallback.cpp
rename to vehicle/2.0/default/vehicle_hal_manager/VehicleCallback.cpp
diff --git a/vehicle/2.0/default/VehicleCallback.h b/vehicle/2.0/default/vehicle_hal_manager/VehicleCallback.h
similarity index 100%
rename from vehicle/2.0/default/VehicleCallback.h
rename to vehicle/2.0/default/vehicle_hal_manager/VehicleCallback.h
diff --git a/vehicle/2.0/default/vehicle_hal_manager/VehicleHalManager.cpp b/vehicle/2.0/default/vehicle_hal_manager/VehicleHalManager.cpp
new file mode 100644
index 0000000..8638131
--- /dev/null
+++ b/vehicle/2.0/default/vehicle_hal_manager/VehicleHalManager.cpp
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+#define LOG_TAG "android.hardware.vehicle@2.0-impl"
+
+#include <cmath>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <hidl/Status.h>
+
+#include "VehicleHalManager.h"
+
+namespace android {
+namespace hardware {
+namespace vehicle {
+namespace V2_0 {
+
+using namespace std::placeholders;
+
+constexpr std::chrono::milliseconds kHalEventBatchingTimeWindow(10);
+
+/**
+ * Indicates what's the maximum size of hidl_vec<VehiclePropValue> we want
+ * to store in reusable object pool.
+ */
+constexpr auto kMaxHidlVecOfVehiclPropValuePoolSize = 20;
+
+Return<void> VehicleHalManager::getAllPropConfigs(
+        getAllPropConfigs_cb _hidl_cb) {
+    hidl_vec<VehiclePropConfig> hidlConfigs;
+    auto& halConfig = mConfigIndex->getAllConfigs();
+
+    hidlConfigs.setToExternal(
+            const_cast<VehiclePropConfig *>(halConfig.data()),
+            halConfig.size());
+
+    _hidl_cb(hidlConfigs);
+
+    return hardware::Return<void>();
+}
+
+Return<void> VehicleHalManager::getPropConfigs(
+        const hidl_vec<VehicleProperty> &properties,
+        getPropConfigs_cb _hidl_cb) {
+    Vector<VehiclePropConfig> configs;
+    for (size_t i = 0; i < properties.size(); i++) {
+        VehicleProperty prop = properties[i];
+        if (mConfigIndex->hasConfig(prop)) {
+            configs.add(mConfigIndex->getConfig(prop));
+        } else {
+            // TODO: return error
+        }
+    }
+
+    hidl_vec<VehiclePropConfig> hidlConfigs;
+    hidlConfigs.setToExternal(
+            const_cast<VehiclePropConfig*>(configs.array()),
+            configs.size());
+
+    _hidl_cb(hidlConfigs);
+
+    return hardware::Return<void>();
+}
+
+Return<void> VehicleHalManager::get(
+        VehicleProperty propId, int32_t areaId, get_cb _hidl_cb) {
+
+    return hardware::Return<void>();
+}
+
+Return<StatusCode> VehicleHalManager::set(const VehiclePropValue &value) {
+    // TODO(pavelm): check permission, etc
+    // TODO(pavelm): check SET subscription
+    // TODO(pavelm): propagate SET call to VehicleHal
+    return hardware::Return<StatusCode>(StatusCode::OK);
+}
+
+Return<StatusCode> VehicleHalManager::subscribe(
+        const sp<IVehicleCallback> &callback,
+        const hidl_vec<SubscribeOptions> &options) {
+    hidl_vec<SubscribeOptions> verifiedOptions(options);
+    for (size_t i = 0; i < verifiedOptions.size(); i++) {
+        SubscribeOptions& ops = verifiedOptions[i];
+        VehicleProperty prop = ops.propId;
+
+        if (!mConfigIndex->hasConfig(prop)) {
+            ALOGE("Failed to subscribe: config not found for property: 0x%x",
+                  prop);
+            return invalidArg();
+        }
+        const VehiclePropConfig& config = mConfigIndex->getConfig(prop);
+
+        if (!isSubscribable(config)) {
+            ALOGE("Failed to subscribe: property is not subscribable: 0x%x",
+                  prop);
+            return invalidArg();
+        }
+
+
+        int32_t areas = isGlobalProp(prop) ? 0 : ops.vehicleAreas;
+        if (areas != 0 && ((areas & config.supportedAreas) != areas)) {
+            ALOGE("Failed to subscribe property 0x%x. Requested areas 0x%x are "
+                  "out of supported range of 0x%x", prop, ops.vehicleAreas,
+                  config.supportedAreas);
+            return invalidArg();
+        }
+
+        ops.vehicleAreas = areas;
+        ops.sampleRate = checkSampleRate(config, ops.sampleRate);
+    }
+
+     std::list<SubscribeOptions> updatedOptions =
+         mSubscriptionManager.addOrUpdateSubscription(callback,
+                                                      verifiedOptions);
+
+    for (auto opt : updatedOptions) {
+        mHal->subscribe(opt.propId, opt.vehicleAreas, opt.sampleRate);
+    }
+
+    // TODO(pavelm): call immediately onHalEvent method during subscription
+    // when appropriate
+    // TODO(pavelm): link to death callback (not implemented yet in HIDL)
+
+    return ok();
+}
+
+Return<StatusCode> VehicleHalManager::unsubscribe(
+        const sp<IVehicleCallback>& callback, VehicleProperty propId) {
+    if (mSubscriptionManager.unsubscribe(callback, propId)) {
+        mHal->unsubscribe(propId);
+    }
+    return ok();
+}
+
+Return<void> VehicleHalManager::debugDump(IVehicle::debugDump_cb _hidl_cb) {
+    _hidl_cb("");
+    return hardware::Return<void>();
+}
+
+void VehicleHalManager::init() {
+    ALOGI("VehicleHalManager::init");
+
+    mHidlVecOfVehiclePropValuePool.resize(kMaxHidlVecOfVehiclPropValuePoolSize);
+
+    mBatchingConsumer.run(&mEventQueue,
+                          kHalEventBatchingTimeWindow,
+                          std::bind(&VehicleHalManager::onBatchHalEvent,
+                                    this, _1));
+
+    mHal->init(&mValueObjectPool,
+               std::bind(&VehicleHalManager::onHalEvent, this, _1),
+               std::bind(&VehicleHalManager::onHalError, this, _1, _2, _3));
+
+    // Initialize index with vehicle configurations received from VehicleHal.
+    mConfigIndex.reset(new VehiclePropConfigIndex(mHal->listProperties()));
+}
+
+VehicleHalManager::~VehicleHalManager() {
+    mBatchingConsumer.requestStop();
+    mEventQueue.deactivate();
+    // We have to wait until consumer thread is fully stopped because it may
+    // be in a state of running callback (onBatchHalEvent).
+    mBatchingConsumer.waitStopped();
+    ALOGI("VehicleHalManager::dtor");
+}
+
+void VehicleHalManager::onHalEvent(VehiclePropValuePtr v) {
+    mEventQueue.push(std::move(v));
+}
+
+void VehicleHalManager::onHalError(VehicleProperty property, status_t errorCode,
+                                   VehiclePropertyOperation operation) {
+    // TODO(pavelm): find subscribed clients and propagate error
+}
+
+void VehicleHalManager::onBatchHalEvent(
+        const std::vector<VehiclePropValuePtr>& values) {
+    const auto& clientValues = mSubscriptionManager.distributeValuesToClients(
+            values, SubscribeFlags::HAL_EVENT);
+
+    for (const HalClientValues& cv : clientValues) {
+        int vecSize = cv.values.size();
+        hidl_vec<VehiclePropValue> vec;
+        if (vecSize < kMaxHidlVecOfVehiclPropValuePoolSize) {
+            vec.setToExternal(&mHidlVecOfVehiclePropValuePool[0], vecSize);
+        } else {
+            vec.resize(vecSize);
+        }
+
+        int i = 0;
+        for (VehiclePropValue* pValue : cv.values) {
+            shallowCopy(&(vec)[i++], *pValue);
+        }
+        cv.client->getCallback()->onPropertyEvent(vec);
+    }
+}
+
+bool VehicleHalManager::isSampleRateFixed(VehiclePropertyChangeMode mode) {
+    return (mode & VehiclePropertyChangeMode::ON_SET)
+           || (mode & VehiclePropertyChangeMode::ON_CHANGE);
+}
+
+float VehicleHalManager::checkSampleRate(const VehiclePropConfig &config,
+                                         float sampleRate) {
+    if (isSampleRateFixed(config.changeMode)) {
+        if (std::abs(sampleRate) > std::numeric_limits<float>::epsilon()) {
+            ALOGW("Sample rate is greater than zero for on change type. "
+                      "Ignoring it.");
+        }
+        return 0.0;
+    } else {
+        if (sampleRate > config.maxSampleRate) {
+            ALOGW("Sample rate %f is higher than max %f. Setting sampling rate "
+                      "to max.", sampleRate, config.maxSampleRate);
+            return config.maxSampleRate;
+        }
+        if (sampleRate < config.minSampleRate) {
+            ALOGW("Sample rate %f is lower than min %f. Setting sampling rate "
+                      "to min.", sampleRate, config.minSampleRate);
+            return config.minSampleRate;
+        }
+    }
+    return sampleRate;  // Provided sample rate was good, no changes.
+}
+
+bool VehicleHalManager::isSubscribable(const VehiclePropConfig& config) {
+    if (!(config.access & VehiclePropertyAccess::READ)) {
+        ALOGW("Cannot subscribe, property 0x%x is write only", config.prop);
+        return false;
+    }
+    if (config.changeMode == VehiclePropertyChangeMode::STATIC) {
+        ALOGW("Cannot subscribe, property 0x%x is static", config.prop);
+        return false;
+    }
+
+    //TODO: extend to support event notification for set from android
+    if (config.changeMode == VehiclePropertyChangeMode::POLL) {
+        ALOGW("Cannot subscribe, property 0x%x is poll only", config.prop);
+        return false;
+    }
+    return true;
+}
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace hardware
+}  // namespace android
diff --git a/vehicle/2.0/default/vehicle_hal_manager/VehicleHalManager.h b/vehicle/2.0/default/vehicle_hal_manager/VehicleHalManager.h
new file mode 100644
index 0000000..0353a15
--- /dev/null
+++ b/vehicle/2.0/default/vehicle_hal_manager/VehicleHalManager.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2015 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 android_hardware_vehicle_V2_0_VehicleHalManager_H_
+#define android_hardware_vehicle_V2_0_VehicleHalManager_H_
+
+#include <stdint.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <memory>
+#include <map>
+#include <set>
+#include <list>
+
+#include <hwbinder/IPCThreadState.h>
+
+#include <android/hardware/vehicle/2.0/IVehicle.h>
+
+#include "VehicleHal.h"
+#include "VehiclePropConfigIndex.h"
+#include "ConcurrentQueue.h"
+#include "SubscriptionManager.h"
+#include "VehicleObjectPool.h"
+
+namespace android {
+namespace hardware {
+namespace vehicle {
+namespace V2_0 {
+
+/**
+ * This class is a thick proxy between IVehicle HIDL interface and vendor's implementation.
+ *
+ * It has some boilerplate code like batching and caching property values, checking permissions,
+ * etc. Vendors must implement VehicleHal class.
+ */
+class VehicleHalManager : public IVehicle {
+public:
+    VehicleHalManager(VehicleHal* vehicleHal)
+        : mHal(vehicleHal) {
+        init();
+    }
+
+    virtual ~VehicleHalManager();
+
+    void init();
+
+    // ---------------------------------------------------------------------------------------------
+    // Methods derived from IVehicle
+    Return<void> getAllPropConfigs(getAllPropConfigs_cb _hidl_cb)  override;
+    Return<void> getPropConfigs(const hidl_vec<VehicleProperty>& properties,
+                                getPropConfigs_cb _hidl_cb)  override;
+    Return<void> get(VehicleProperty propId, int32_t areaId, get_cb _hidl_cb)  override;
+    Return<StatusCode> set(const VehiclePropValue& value)  override;
+    Return<StatusCode> subscribe(const sp<IVehicleCallback>& callback,
+                                const hidl_vec<SubscribeOptions>& options)  override;
+    Return<StatusCode> unsubscribe(const sp<IVehicleCallback>& callback,
+                                   VehicleProperty propId)  override;
+    Return<void> debugDump(debugDump_cb _hidl_cb = nullptr) override;
+
+private:
+    using VehiclePropValuePtr = VehicleHal::VehiclePropValuePtr;
+
+    // ---------------------------------------------------------------------------------------------
+    // Events received from VehicleHal
+    void onHalEvent(VehiclePropValuePtr  v);
+    void onHalError(VehicleProperty property,
+                    status_t errorCode,
+                    VehiclePropertyOperation operation);
+
+    // ---------------------------------------------------------------------------------------------
+    // This method will be called from BatchingConsumer thread
+    void onBatchHalEvent(const std::vector<VehiclePropValuePtr >& values);
+
+    static bool isSubscribable(const VehiclePropConfig& config);
+    static bool isSampleRateFixed(VehiclePropertyChangeMode mode);
+    static float checkSampleRate(const VehiclePropConfig& config,
+                                 float sampleRate);
+
+    static Return<StatusCode> ok() {
+        return Return<StatusCode>(StatusCode::OK);
+    }
+    static Return<StatusCode> invalidArg() {
+        return Return<StatusCode>(StatusCode::INVALID_ARG);
+    }
+
+private:
+    VehicleHal* mHal;
+    std::unique_ptr<VehiclePropConfigIndex> mConfigIndex;
+    SubscriptionManager mSubscriptionManager;
+
+    hidl_vec<VehiclePropValue> mHidlVecOfVehiclePropValuePool;
+
+    ConcurrentQueue<VehiclePropValuePtr> mEventQueue;
+    BatchingConsumer<VehiclePropValuePtr> mBatchingConsumer;
+    VehiclePropValuePool mValueObjectPool;
+};
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace hardware
+}  // namespace android
+
+
+#endif // android_hardware_vehicle_V2_0_VehicleHalManager_H_
diff --git a/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.h b/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.h
new file mode 100644
index 0000000..02bfb3f
--- /dev/null
+++ b/vehicle/2.0/default/vehicle_hal_manager/VehicleObjectPool.h
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2016 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 android_hardware_vehicle_V2_0_VehicleObjectPool_H_
+#define android_hardware_vehicle_V2_0_VehicleObjectPool_H_
+
+#include <iostream>
+#include <memory>
+#include <deque>
+#include <string>
+#include <map>
+#include <mutex>
+
+#include <android/hardware/vehicle/2.0/types.h>
+
+#include "VehicleUtils.h"
+
+namespace android {
+namespace hardware {
+namespace vehicle {
+namespace V2_0 {
+
+using android::hardware::hidl_vec;
+
+// Handy metric mostly for unit tests and debug.
+#define INC_METRIC_IF_DEBUG(val) PoolStats::instance()->val++;
+struct PoolStats {
+    std::atomic<uint32_t> Obtained {0};
+    std::atomic<uint32_t> Created {0};
+    std::atomic<uint32_t> Recycled {0};
+
+    static PoolStats* instance() {
+        static PoolStats inst;
+        return &inst;
+    }
+};
+
+/**
+ * Generic abstract object pool class. Users of this class must implement
+ * #createObject method.
+ *
+ * This class is thread-safe. Concurrent calls to #obtain(...) method from
+ * multiple threads is OK, also client can obtain an object in one thread and
+ * then move ownership to another thread.
+ *
+ */
+template<typename T>
+class ObjectPool {
+public:
+    ObjectPool() = default;
+    virtual ~ObjectPool() = default;
+
+    struct Deleter  {
+        using OnDeleteFunc = std::function<void(T*)>;
+
+        Deleter(const OnDeleteFunc& f) : mOnDelete(f) {};
+
+        Deleter() = default;
+        Deleter(const Deleter&) = default;
+
+        void operator()(T* o) {
+            mOnDelete(o);
+        }
+    private:
+        OnDeleteFunc mOnDelete;
+    };
+
+    using RecyclableType = std::unique_ptr<T, Deleter>;
+
+    virtual RecyclableType obtain() {
+        std::lock_guard<std::mutex> g(mLock);
+        INC_METRIC_IF_DEBUG(Obtained)
+        if (mObjects.empty()) {
+            INC_METRIC_IF_DEBUG(Created)
+            return wrap(createObject());
+        }
+
+        auto o = wrap(mObjects.front().release());
+        mObjects.pop_front();
+
+        return o;
+    }
+
+    ObjectPool& operator =(const ObjectPool &) = delete;
+    ObjectPool(const ObjectPool &) = delete;
+
+protected:
+    virtual T* createObject() = 0;
+
+    virtual void recycle(T* o) {
+        INC_METRIC_IF_DEBUG(Recycled)
+        std::lock_guard<std::mutex> g(mLock);
+        mObjects.push_back(std::unique_ptr<T> { o } );
+    }
+
+private:
+    const Deleter& getDeleter() {
+        if (!mDeleter.get()) {
+            Deleter *d = new Deleter(std::bind(&ObjectPool::recycle,
+                                               this,
+                                               std::placeholders::_1));
+            mDeleter.reset(d);
+        }
+        return *mDeleter.get();
+    }
+
+    RecyclableType wrap(T* raw) {
+        return RecyclableType { raw, getDeleter() };
+    }
+
+private:
+    mutable std::mutex mLock;
+    std::deque<std::unique_ptr<T>> mObjects;
+    std::unique_ptr<Deleter> mDeleter;
+};
+
+/**
+ * This is std::unique_ptr<> with custom delete operation that typically moves
+ * the pointer it holds back to ObectPool.
+ */
+template <typename T>
+using recyclable_ptr = typename ObjectPool<T>::RecyclableType;
+
+/**
+ * This class provides a pool of recycable VehiclePropertyValue objects.
+ *
+ * It has only one overloaded public method - obtain(...), users must call this
+ * method when new object is needed with given VehiclePropertyType and vector
+ * size (for vector properties). This method returns a recycable smart pointer
+ * to VehiclePropertyValue, essentially this is a std::unique_ptr with custom
+ * delete function, so recycable object has only one owner and developers can
+ * safely pass it around. Once this object goes out of scope, it will be
+ * returned the the object pool.
+ *
+ * Some objects are not recycable: strings and vector data types with
+ * vector length > maxRecyclableVectorSize (provided in the constructor). These
+ * objects will be deleted immediately once the go out of scope. There's no
+ * synchornization penalty for these objects since we do not store them in the
+ * pool.
+ *
+ * This class is thread-safe. Users can obtain an object in one thread and pass
+ * it to another.
+ *
+ * Sample usage:
+ *
+ *   VehiclePropValuePool pool;
+ *   auto v = pool.obtain(VehiclePropertyType::INT32);
+ *   v->propId = VehicleProperty::HVAC_FAN_SPEED;
+ *   v->areaId = VehicleAreaZone::ROW_1_LEFT;
+ *   v->timestamp = elapsedRealtimeNano();
+ *   v->value->int32Values[0] = 42;
+ *
+ *
+ */
+class VehiclePropValuePool {
+public:
+    using RecyclableType = recyclable_ptr<VehiclePropValue>;
+
+    /**
+     * Creates VehiclePropValuePool
+     *
+     * @param maxRecyclableVectorSize - vector value types (e.g.
+     * VehiclePropertyType::INT32_VEC) with size equal or less to this value
+     * will be stored in the pool. If users tries to obtain value with vector
+     * size greater than maxRecyclableVectorSize user will receive appropriate
+     * object, but once it goes out of scope it will be deleted immediately, not
+     * returning back to the object pool.
+     *
+     */
+    VehiclePropValuePool(size_t maxRecyclableVectorSize = 4) :
+        mMaxRecyclableVectorSize(maxRecyclableVectorSize) { };
+
+    RecyclableType obtain(VehiclePropertyType type) {
+        return obtain(type, 1);
+    }
+
+    RecyclableType obtain(VehiclePropertyType type, size_t vecSize) {
+        return isDisposable(type, vecSize)
+                ? obtainDisposable(type, vecSize)
+                : obtainRecylable(type, vecSize);
+    }
+
+    RecyclableType obtain(const VehiclePropValue& src) {
+        VehiclePropertyType type = getPropType(src.prop);
+        size_t vecSize = getVehicleRawValueVectorSize(src.value, type);;
+        auto dest = obtain(type, vecSize);
+
+        dest->prop = src.prop;
+        dest->areaId = src.areaId;
+        dest->timestamp = src.timestamp;
+        copyVehicleRawValue(&dest->value, src.value);
+
+        return dest;
+    }
+
+    RecyclableType obtainInt32(int32_t value) {
+        auto val = obtain(VehiclePropertyType::INT32);
+        val->value.int32Values[0] = value;
+        return val;
+    }
+
+    RecyclableType obtainInt64(int64_t value) {
+        auto val = obtain(VehiclePropertyType::INT64);
+        val->value.int64Values[0] = value;
+        return val;
+    }
+
+    RecyclableType obtainFloat(float value) {
+        auto val = obtain(VehiclePropertyType::FLOAT);
+        val->value.floatValues[0] = value;
+        return val;
+    }
+
+    RecyclableType obtainString(const char* cstr) {
+        auto val = obtain(VehiclePropertyType::STRING);
+        val->value.stringValue = cstr;
+        return val;
+    }
+
+    VehiclePropValuePool(VehiclePropValuePool& ) = delete;
+    VehiclePropValuePool& operator=(VehiclePropValuePool&) = delete;
+
+private:
+    bool isDisposable(VehiclePropertyType type, size_t vecSize) const {
+        return vecSize > mMaxRecyclableVectorSize ||
+               VehiclePropertyType::STRING == type;
+    }
+
+    RecyclableType obtainDisposable(VehiclePropertyType valueType,
+                                    size_t vectorSize) const {
+        return RecyclableType {
+            createVehiclePropValue(valueType, vectorSize).release(),
+            mDisposableDeleter
+        };
+    }
+
+    RecyclableType obtainRecylable(VehiclePropertyType type, size_t vecSize) {
+        // VehiclePropertyType is not overlapping with vectorSize.
+        int32_t key = static_cast<int32_t>(type)
+                      | static_cast<int32_t>(vecSize);
+
+        std::lock_guard<std::mutex> g(mLock);
+        auto it = mValueTypePools.find(key);
+
+        if (it == mValueTypePools.end()) {
+            auto newPool(std::make_unique<InternalPool>(type, vecSize));
+            it = mValueTypePools.emplace(key, std::move(newPool)).first;
+        }
+        return it->second->obtain();
+    }
+
+    class InternalPool: public ObjectPool<VehiclePropValue> {
+    public:
+        InternalPool(VehiclePropertyType type, size_t vectorSize)
+            : mPropType(type), mVectorSize(vectorSize) {
+        }
+
+        RecyclableType obtain() {
+            return ObjectPool<VehiclePropValue>::obtain();
+        }
+    protected:
+        VehiclePropValue* createObject() override {
+            return createVehiclePropValue(mPropType, mVectorSize).release();
+        }
+
+        void recycle(VehiclePropValue* o) override {
+            ALOGE_IF(o == nullptr, "Attempt to recycle nullptr");
+
+            if (!check(&o->value)) {
+                ALOGE("Discarding value for prop 0x%x because it contains "
+                          "data that is not consistent with this pool. "
+                          "Expected type: %d, vector size: %d",
+                      o->prop, mPropType, mVectorSize);
+                delete o;
+            }
+            ObjectPool<VehiclePropValue>::recycle(o);
+        }
+
+    private:
+        bool check(VehiclePropValue::RawValue* v) {
+            return check(&v->int32Values,
+                         (VehiclePropertyType::INT32 == mPropType
+                             || VehiclePropertyType::INT32_VEC == mPropType
+                             || VehiclePropertyType::BOOLEAN == mPropType))
+                    && check(&v->floatValues,
+                             (VehiclePropertyType::FLOAT == mPropType
+                              || VehiclePropertyType::FLOAT_VEC == mPropType))
+                    && check(&v->int64Values,
+                             VehiclePropertyType::INT64 == mPropType)
+                    && check(&v->bytes,
+                             VehiclePropertyType::BYTES == mPropType)
+                    && v->stringValue.size() == 0;
+        }
+
+        template <typename VecType>
+        bool check(hidl_vec<VecType>* vec, bool expected) {
+            return vec->size() == (expected ? mVectorSize : 0);
+        }
+    private:
+        VehiclePropertyType mPropType;
+        size_t mVectorSize;
+    };
+
+private:
+    const ObjectPool<VehiclePropValue>::Deleter mDisposableDeleter {
+        [] (VehiclePropValue* v) {
+            delete v;
+        }
+    };
+
+private:
+    mutable std::mutex mLock;
+    const size_t mMaxRecyclableVectorSize;
+    std::map<int32_t, std::unique_ptr<InternalPool>> mValueTypePools;
+};
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace hardware
+}  // namespace android
+
+#endif // android_hardware_vehicle_V2_0_VehicleObjectPool_H_
diff --git a/vehicle/2.0/default/vehicle_hal_manager/VehiclePropConfigIndex.h b/vehicle/2.0/default/vehicle_hal_manager/VehiclePropConfigIndex.h
new file mode 100644
index 0000000..540fc33
--- /dev/null
+++ b/vehicle/2.0/default/vehicle_hal_manager/VehiclePropConfigIndex.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016 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 android_hardware_vehicle_V2_0_VehiclePropConfigIndex_H_
+#define android_hardware_vehicle_V2_0_VehiclePropConfigIndex_H_
+
+#include <utils/KeyedVector.h>
+
+#include <android/hardware/vehicle/2.0/IVehicle.h>
+
+namespace android {
+namespace hardware {
+namespace vehicle {
+namespace V2_0 {
+
+/*
+ * This is thread-safe immutable class to hold vehicle property configuration
+ * data.
+ */
+class VehiclePropConfigIndex {
+public:
+    VehiclePropConfigIndex(
+        const std::vector<VehiclePropConfig>& properties)
+        : mConfigs(properties), mPropToConfig(mConfigs)
+    {}
+
+    bool hasConfig(VehicleProperty property) const {
+        return mPropToConfig.indexOfKey(property) >= 0;
+    }
+
+    const VehiclePropConfig& getConfig(VehicleProperty property) const {
+        return *mPropToConfig.valueFor(property);
+    }
+
+    const std::vector<VehiclePropConfig>& getAllConfigs() const {
+        return mConfigs;
+    }
+
+private:
+    typedef KeyedVector<VehicleProperty, const VehiclePropConfig*> PropConfigMap;
+    class ImmutablePropConfigMap : private PropConfigMap {
+    public:
+        ImmutablePropConfigMap(const std::vector<VehiclePropConfig>& configs) {
+            setCapacity(configs.size());
+            for (auto& config : configs) {
+                add(config.prop, &config);
+            }
+        }
+    public:
+        using PropConfigMap::valueFor;
+        using PropConfigMap::indexOfKey;
+    };
+
+private:
+    const std::vector<VehiclePropConfig> mConfigs;
+    const ImmutablePropConfigMap mPropToConfig;  // mConfigs must be declared
+                                                 // first.
+};
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace hardware
+}  // namespace android
+
+#endif // android_hardware_vehicle_V2_0_VehiclePropConfigIndex_H_
diff --git a/vehicle/2.0/default/vehicle_hal_manager/VehicleUtils.h b/vehicle/2.0/default/vehicle_hal_manager/VehicleUtils.h
new file mode 100644
index 0000000..f23a235
--- /dev/null
+++ b/vehicle/2.0/default/vehicle_hal_manager/VehicleUtils.h
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2016 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 android_hardware_vehicle_V2_0_VehicleUtils_H_
+#define android_hardware_vehicle_V2_0_VehicleUtils_H_
+
+#include <memory>
+
+#include <hidl/HidlSupport.h>
+
+#include <android/hardware/vehicle/2.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace vehicle {
+namespace V2_0 {
+
+/** Represents all supported areas for a property. Can be used is  */
+constexpr int32_t kAllSupportedAreas = 0;
+
+template <typename T>
+inline hidl_vec<T> init_hidl_vec(std::initializer_list<const T> values) {
+    hidl_vec<T> vector;
+    vector.resize(values.size());
+    size_t i = 0;
+    for (auto& c : values) {
+        vector[i++] = c;
+    }
+    return vector;
+}
+
+/**
+ * Logical 'and' operator for class enums. The return type will be enum's
+ * underline type
+ */
+template <typename ENUM>
+inline typename std::underlying_type<ENUM>::type operator &(ENUM v1, ENUM v2) {
+    return static_cast<typename std::underlying_type<ENUM>::type>(v1)
+           & static_cast<typename std::underlying_type<ENUM>::type>(v2);
+}
+
+/** Returns underlying (integer) value for given enum. */
+template <typename ENUM>
+inline typename std::underlying_type<ENUM>::type val(ENUM const value) {
+    return static_cast<typename std::underlying_type<ENUM>::type>(value);
+}
+
+inline VehiclePropertyType getPropType(VehicleProperty prop) {
+    return static_cast<VehiclePropertyType>(
+            static_cast<int32_t>(prop)
+            & static_cast<int32_t>(VehiclePropertyType::MASK));
+}
+
+inline VehiclePropertyGroup getPropGroup(VehicleProperty prop) {
+    return static_cast<VehiclePropertyGroup>(
+                static_cast<int32_t>(prop)
+                & static_cast<int32_t>(VehiclePropertyGroup::MASK));
+}
+
+inline VehicleArea getPropArea(VehicleProperty prop) {
+    return static_cast<VehicleArea>(
+        static_cast<int32_t>(prop) & static_cast<int32_t>(VehicleArea::MASK));
+}
+
+inline bool isGlobalProp(VehicleProperty prop) {
+    return getPropArea(prop) == VehicleArea::GLOBAL;
+}
+
+inline bool checkPropType(VehicleProperty prop, VehiclePropertyType type) {
+    return getPropType(prop) == type;
+}
+
+inline bool isSystemProperty(VehicleProperty prop) {
+    return VehiclePropertyGroup::SYSTEM == getPropGroup(prop);
+}
+
+inline std::unique_ptr<VehiclePropValue> createVehiclePropValue(
+    VehiclePropertyType type, size_t vecSize) {
+    auto val = std::unique_ptr<VehiclePropValue>(new VehiclePropValue);
+    switch (type) {
+        case VehiclePropertyType::INT32:      // fall through
+        case VehiclePropertyType::INT32_VEC:  // fall through
+        case VehiclePropertyType::BOOLEAN:
+            val->value.int32Values.resize(vecSize);
+            break;
+        case VehiclePropertyType::FLOAT:
+        case VehiclePropertyType::FLOAT_VEC:  // fall through
+            val->value.floatValues.resize(vecSize);
+            break;
+        case VehiclePropertyType::INT64:
+            val->value.int64Values.resize(vecSize);
+            break;
+        case VehiclePropertyType::BYTES:
+            val->value.bytes.resize(vecSize);
+            break;
+        case VehiclePropertyType::STRING:
+            break; // Valid, but nothing to do.
+        default:
+            ALOGE("createVehiclePropValue: unknown type: %d", type);
+            val.reset(nullptr);
+    }
+    return val;
+}
+
+inline size_t getVehicleRawValueVectorSize(
+        const VehiclePropValue::RawValue& value, VehiclePropertyType type) {
+    switch (type) {
+        case VehiclePropertyType::INT32:      // fall through
+        case VehiclePropertyType::INT32_VEC:  // fall through
+        case VehiclePropertyType::BOOLEAN:
+            return value.int32Values.size();
+        case VehiclePropertyType::FLOAT:      // fall through
+        case VehiclePropertyType::FLOAT_VEC:
+            return value.floatValues.size();
+        case VehiclePropertyType::INT64:
+            return value.int64Values.size();
+        case VehiclePropertyType::BYTES:
+            return value.bytes.size();
+        default:
+            return 0;
+    }
+}
+
+/** Copies vector src to dest, dest should have enough space. */
+template <typename T>
+inline void copyHidlVec(hidl_vec<T>* dest, const hidl_vec<T>& src) {
+    for (size_t i = 0; i < std::min(dest->size(), src.size()); i++) {
+        (*dest)[i] = src[i];
+    }
+}
+
+inline void copyVehicleRawValue(VehiclePropValue::RawValue* dest,
+                                const VehiclePropValue::RawValue& src) {
+    copyHidlVec(&dest->int32Values, src.int32Values);
+    copyHidlVec(&dest->floatValues, src.floatValues);
+    copyHidlVec(&dest->int64Values, src.int64Values);
+    copyHidlVec(&dest->bytes, src.bytes);
+    dest->stringValue = src.stringValue;
+}
+
+template <typename T>
+inline void shallowCopyHidlVec(hidl_vec<T>* dest, const hidl_vec<T>& src) {
+    if (src.size() > 0) {
+        dest->setToExternal(const_cast<T*>(&src[0]), src.size());
+    } else if (dest->size() > 0) {
+        dest->resize(0);
+    }
+}
+
+inline void shallowCopyHidlStr(hidl_string* dest, const hidl_string& src ) {
+    if (!src.empty()) {
+        dest->setToExternal(src.c_str(), src.size());
+    } else if (dest->size() > 0) {
+        dest->setToExternal(0, 0);
+    }
+}
+
+inline void shallowCopy(VehiclePropValue* dest,
+                        const VehiclePropValue& src) {
+    dest->prop = src.prop;
+    dest->areaId = src.areaId;
+    dest->timestamp = src.timestamp;
+    shallowCopyHidlVec(&dest->value.int32Values, src.value.int32Values);
+    shallowCopyHidlVec(&dest->value.int64Values, src.value.int64Values);
+    shallowCopyHidlVec(&dest->value.floatValues, src.value.floatValues);
+    shallowCopyHidlVec(&dest->value.bytes, src.value.bytes);
+    shallowCopyHidlStr(&dest->value.stringValue, src.value.stringValue);
+}
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace hardware
+}  // namespace android
+
+#endif // android_hardware_vehicle_V2_0_VehicleUtils_H_
