Here is the first increment - create C++ IMM wrapper for IMM API.
Aim to create simple and easy interfaces for using IMM.
---
 Makefile.am                                        |   1 +
 src/immwrp/Makefile                                |  22 ++
 src/immwrp/Makefile.am                             | 112 ++++++++
 src/immwrp/README                                  | 141 ++++++++++
 src/immwrp/apitest/Makefile                        |  22 ++
 src/immwrp/apitest/common.h                        |  69 +++++
 src/immwrp/apitest/immwrp_test_classes.xml         | 227 +++++++++++++++
 src/immwrp/apitest/immwrptest.cc                   |  83 ++++++
 src/immwrp/apitest/omclassmanagement.cc            | 194 +++++++++++++
 src/immwrp/apitest/omclassmanagement.h             |  23 ++
 src/immwrp/apitest/omsearchnext.cc                 | 311 +++++++++++++++++++++
 src/immwrp/apitest/omsearchnext.h                  |  23 ++
 src/immwrp/immom/Makefile                          |  18 ++
 src/immwrp/immom/om_class_description_get.cc       |  57 ++++
 src/immwrp/immom/om_class_description_get.h        | 101 +++++++
 .../immom/om_class_description_memory_free.cc      |  53 ++++
 .../immom/om_class_description_memory_free.h       |  48 ++++
 src/immwrp/immom/om_class_management.h             |  24 ++
 src/immwrp/immom/om_common.h                       |  77 +++++
 src/immwrp/immom/om_finalize.cc                    |  46 +++
 src/immwrp/immom/om_finalize.h                     |  37 +++
 src/immwrp/immom/om_handle.h                       |  24 ++
 src/immwrp/immom/om_initialize.cc                  |  57 ++++
 src/immwrp/immom/om_initialize.h                   |  46 +++
 src/immwrp/immom/om_search.h                       |  25 ++
 src/immwrp/immom/om_search_finalize.cc             |  46 +++
 src/immwrp/immom/om_search_finalize.h              |  41 +++
 src/immwrp/immom/om_search_init.cc                 |  90 ++++++
 src/immwrp/immom/om_search_init.h                  | 160 +++++++++++
 src/immwrp/immom/om_search_next.cc                 |  61 ++++
 src/immwrp/immom/om_search_next.h                  | 138 +++++++++
 src/immwrp/tests/Makefile                          |  19 ++
 src/immwrp/tests/common.h                          |  40 +++
 src/immwrp/tests/omclassmanagement_test.cc         | 204 ++++++++++++++
 src/immwrp/tests/omsearchnext_test.cc              | 288 +++++++++++++++++++
 35 files changed, 2928 insertions(+)
 create mode 100644 src/immwrp/Makefile
 create mode 100644 src/immwrp/Makefile.am
 create mode 100644 src/immwrp/README
 create mode 100644 src/immwrp/apitest/Makefile
 create mode 100644 src/immwrp/apitest/common.h
 create mode 100644 src/immwrp/apitest/immwrp_test_classes.xml
 create mode 100644 src/immwrp/apitest/immwrptest.cc
 create mode 100644 src/immwrp/apitest/omclassmanagement.cc
 create mode 100644 src/immwrp/apitest/omclassmanagement.h
 create mode 100644 src/immwrp/apitest/omsearchnext.cc
 create mode 100644 src/immwrp/apitest/omsearchnext.h
 create mode 100644 src/immwrp/immom/Makefile
 create mode 100644 src/immwrp/immom/om_class_description_get.cc
 create mode 100644 src/immwrp/immom/om_class_description_get.h
 create mode 100644 src/immwrp/immom/om_class_description_memory_free.cc
 create mode 100644 src/immwrp/immom/om_class_description_memory_free.h
 create mode 100644 src/immwrp/immom/om_class_management.h
 create mode 100644 src/immwrp/immom/om_common.h
 create mode 100644 src/immwrp/immom/om_finalize.cc
 create mode 100644 src/immwrp/immom/om_finalize.h
 create mode 100644 src/immwrp/immom/om_handle.h
 create mode 100644 src/immwrp/immom/om_initialize.cc
 create mode 100644 src/immwrp/immom/om_initialize.h
 create mode 100644 src/immwrp/immom/om_search.h
 create mode 100644 src/immwrp/immom/om_search_finalize.cc
 create mode 100644 src/immwrp/immom/om_search_finalize.h
 create mode 100644 src/immwrp/immom/om_search_init.cc
 create mode 100644 src/immwrp/immom/om_search_init.h
 create mode 100644 src/immwrp/immom/om_search_next.cc
 create mode 100644 src/immwrp/immom/om_search_next.h
 create mode 100644 src/immwrp/tests/Makefile
 create mode 100644 src/immwrp/tests/common.h
 create mode 100644 src/immwrp/tests/omclassmanagement_test.cc
 create mode 100644 src/immwrp/tests/omsearchnext_test.cc

diff --git a/Makefile.am b/Makefile.am
index a8d0594..901f6f5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -160,6 +160,7 @@ include $(top_srcdir)/src/dtm/Makefile.am
 include $(top_srcdir)/src/evt/Makefile.am
 include $(top_srcdir)/src/fm/Makefile.am
 include $(top_srcdir)/src/imm/Makefile.am
+include $(top_srcdir)/src/immwrp/Makefile.am
 include $(top_srcdir)/src/lck/Makefile.am
 include $(top_srcdir)/src/libjava/Makefile.am
 include $(top_srcdir)/src/log/Makefile.am
diff --git a/src/immwrp/Makefile b/src/immwrp/Makefile
new file mode 100644
index 0000000..e530329
--- /dev/null
+++ b/src/immwrp/Makefile
@@ -0,0 +1,22 @@
+#      -*- OpenSAF  -*-
+#
+# (C) Copyright 2017 The OpenSAF Foundation
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+# under the GNU Lesser General Public License Version 2.1, February 1999.
+# The complete license can be accessed from the following location:
+# http://opensource.org/licenses/lgpl-license.php
+# See the Copying file included with the OpenSAF distribution for full
+# licensing terms.
+#
+# Author(s): Ericsson AB
+#
+
+all:
+       $(MAKE) -C ../.. lib/libopensaf_immwrp.la
+
+check:
+       $(MAKE) -C ../.. bin/testimmwrp
+       ../../bin/testimmwrp
diff --git a/src/immwrp/Makefile.am b/src/immwrp/Makefile.am
new file mode 100644
index 0000000..76eac99
--- /dev/null
+++ b/src/immwrp/Makefile.am
@@ -0,0 +1,112 @@
+#      -*- OpenSAF  -*-
+#
+# Copyright Ericsson AB 2017 - All Rights Reserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+# under the GNU Lesser General Public License Version 2.1, February 1999.
+# The complete license can be accessed from the following location:
+# http://opensource.org/licenses/lgpl-license.php
+# See the Copying file included with the OpenSAF distribution for full
+# licensing terms.
+#
+# Author(s): Ericsson AB
+#
+
+pkglib_LTLIBRARIES += lib/libopensaf_immwrp.la
+
+lib_libopensaf_immwrp_la_CFLAGS = $(OSAF_LIB_FLAGS) $(AM_CFLAGS)
+
+lib_libopensaf_immwrp_la_CXXFLAGS = $(OSAF_LIB_FLAGS) $(AM_CXXFLAGS)
+
+lib_libopensaf_immwrp_la_LDFLAGS = \
+       $(AM_LDFLAGS) \
+       -version-number 0:2:0
+
+lib_libopensaf_immwrp_la_SOURCES = \
+       src/immwrp/immom/om_initialize.cc \
+       src/immwrp/immom/om_finalize.cc \
+       src/immwrp/immom/om_search_init.cc \
+       src/immwrp/immom/om_search_next.cc \
+       src/immwrp/immom/om_search_finalize.cc \
+       src/immwrp/immom/om_class_description_get.cc \
+       src/immwrp/immom/om_class_description_memory_free.cc
+
+nodist_EXTRA_lib_libopensaf_immwrp_la_SOURCES = dummy.cc
+
+lib_libopensaf_immwrp_la_LIBADD = \
+       lib/libosaf_common.la \
+       lib/libSaImmOm.la \
+       lib/libSaImmOi.la \
+       lib/libopensaf_core.la
+
+noinst_HEADERS += \
+       src/immwrp/immom/om_common.h \
+       src/immwrp/immom/om_handle.h \
+       src/immwrp/immom/om_search.h \
+       src/immwrp/immom/om_initialize.h \
+       src/immwrp/immom/om_finalize.h \
+       src/immwrp/immom/om_search_init.h \
+       src/immwrp/immom/om_search_next.h \
+       src/immwrp/immom/om_search_finalize.h \
+       src/immwrp/immom/om_class_description_get.h \
+       src/immwrp/immom/om_class_description_memory_free.h \
+       src/immwrp/immom/om_class_management.h
+
+CORE_INCLUDES += -I$(top_srcdir)/src/osaf/saf \
+               -I$(top_srcdir)
+
+TESTS += bin/testimmwrp
+
+bin_testimmwrp_CXXFLAGS =$(AM_CXXFLAGS)
+
+bin_testimmwrp_CPPFLAGS = \
+       -DSA_EXTENDED_NAME_SOURCE \
+       $(AM_CPPFLAGS) \
+       -I$(GTEST_DIR)/include
+
+bin_testimmwrp_LDFLAGS = \
+       $(AM_LDFLAGS)
+
+noinst_HEADERS += \
+       src/immwrp/tests/common.h
+
+bin_testimmwrp_SOURCES = \
+       src/immwrp/tests/omclassmanagement_test.cc \
+       src/immwrp/tests/omsearchnext_test.cc
+
+bin_testimmwrp_LDADD = \
+       $(GTEST_DIR)/lib/libgtest.la \
+       $(GTEST_DIR)/lib/libgtest_main.la \
+       lib/libopensaf_core.la \
+       lib/libopensaf_immwrp.la
+
+if ENABLE_TESTS
+
+bin_PROGRAMS += bin/immwrptest
+
+noinst_HEADERS += \
+       src/immwrp/apitest/common.h \
+       src/immwrp/apitest/omclassmanagement.h \
+       src/immwrp/apitest/omsearchnext.h
+
+bin_immwrptest_CFLAGS = $(AM_CFLAGS) -Wformat=1
+
+bin_immwrptest_CPPFLAGS = \
+       -DSA_EXTENDED_NAME_SOURCE \
+       $(AM_CPPFLAGS)
+
+bin_immwrptest_SOURCES = \
+       src/immwrp/apitest/omsearchnext.cc \
+       src/immwrp/apitest/omclassmanagement.cc \
+       src/immwrp/apitest/immwrptest.cc
+
+bin_immwrptest_LDADD = \
+       lib/libosaf_common.la \
+       lib/libSaImmOi.la \
+       lib/libSaImmOm.la \
+       lib/libopensaf_core.la \
+       lib/libopensaf_immwrp.la
+
+endif
diff --git a/src/immwrp/README b/src/immwrp/README
new file mode 100644
index 0000000..7b45141
--- /dev/null
+++ b/src/immwrp/README
@@ -0,0 +1,141 @@
+##############################################
+# ABOUT DESIGN RULES and APIs USAGE
+##############################################
+
+I) First increment
+- One IMM C API will be represented by one C++ class
+- Get rid of void pointer, pointer to poiter or complicated input parameters
+- Provide easy and simple interfaces to set/get IMM info.
+
+II) Second increment
+
+##############################################
+# EXAMPLE and EXPLANATION
+##############################################
+
+This example shows the sequence used to read IMM attributes
+with many different data types, as well as multiple-value attributes
+and single-value attributes.
+
+(Refer to full source code at /src/immwrp/tests/immwrptest.cc)
+
+I) Initialize OM Handle.
+--------------------------------------------------------------------------------
+// Create an `ImmOmInitialize` obj without imm callbacks.
+ImmOmInitialize omhandle(immVersion);
+
+// Acquire IMM OM handle from IMM
+if (omhandle.InitHandle() == false) {
+    std::cerr << "OM handle: InitHandle() failed: " <<
+       saf_error(omhandle.GetAisErr()) << std::endl;
+       return;
+  }
+
+
+II) Intialize IMM OM Search Handle
+--------------------------------------------------------------------------------
+  // Create an IMM OM search object with `OM handle` as input
+  ImmOmSearchInit searchobj(omhandle.GetHandle());
+
+  // Setup parameter for searching object.
+  const char* className = "ImmWrpTestConfig";
+  const char* attrName = "SaImmAttrClassName";
+  searchobj.SetScope(SA_IMM_SUBTREE);
+  searchobj.SetOpt(SA_IMM_SEARCH_ONE_ATTR | SA_IMM_SEARCH_GET_ALL_ATTR);
+  searchobj.SetParam(attrName, SA_IMM_ATTR_SASTRINGT, &className);
+
+  // Acquire Search Handle from IMM
+  if (searchobj.InitHandle() == false) {
+    std::cerr << "Search Obj: InitHandle() failed: " <<
+       saf_error(searchobj.GetAisErr()) << std::endl;
+    omfinalize.FinalizeHandle();
+    return;
+  }
+
+
+III) Perform Search Action & Query Attribute values
+--------------------------------------------------------------------------------
+  // Create Search Next object with `OM handle` & `Search handle` as inputs
+  ImmOmSearchNext searchnext(omhandle.GetHandle(), searchobj.GetHandle());
+
+  // Perform Search action
+  if (searchnext.Execute() == false) {
+    std::cerr << "Search Obj: Execute() failed: " <<
+       saf_error(searchobj.GetAisErr()) << std::endl;
+
+    omsearchfinalize.FinalizeHandle();
+    omfinalize.FinalizeHandle();
+    return;
+  }
+
+  // Query attribute values for a specific input attribute @name
+  // Refer to `GetSingleValue` or `GetMultipleValue` in `immwrptest`
+  std::string dn = searchnext.GetObjName();
+  auto output    = searchnext.GetValue<SaInt32T>(name);
+  auto output    = searchnext.GetValue<SaNameT>(name);
+  auto output    = searchnext.GetValue<SaStringT>(name);
+
+  // Query multiple-value attribute types
+  auto output = searchnext.GetMultiValue<SaStringT>(name);
+  std::cout << name << ":";
+  for (const auto& v : output) {
+    std::cout << v << " ";
+  }
+
+
+IV) Finalize Resources
+--------------------------------------------------------------------------------
+  // Finalize `Search Object` & `Search Object`
+  ImmOmFinalize omfinalize(omhandle.GetHandle());
+  ImmOmSearchFinalize omsearchfinalize(searchobj.GetHandle());
+  omsearchfinalize.FinalizeHandle();
+  omfinalize.FinalizeHandle();
+
+
+
+########################################################
+# HOW TO DEPLOY, RUN immwrptest application, OUTPUT
+########################################################
+
+I) Load IMM model `immwrp_test_classes.xml`
+--------------------------------------------------------------------------------
+   immcfg -f immwrp_test_classes.xml
+
+
+II) Run `immwrptest` and check the results
+--------------------------------------------------------------------------------
+    immwrptest -o
+
+
+III) Output
+--------------------------------------------------------------------------------
+# immcfg -f immwrp_test_classes.xml
+#
+# immwrptest -o
+MULTIPLE VALUES
+===============
+Attribute value of DN: immWrpTestMultipleCfg=testMultipleCfg
+---------------------------
+SaDoubleMultiple: 666668 66666.6
+SaFloatMultiple: 55556.5 5555.5
+SaInt32TMultiple: 223 22
+SaInt64TMultiple: 44445 4444
+SaNameTMultiple: Name2 Name1
+SaStringMultiple: 777778 77777
+SaUint32TMultiple: 112 11
+SaUint64TMultiple: 33334 3333
+
+SINGLE VALUES
+===============
+Attribute value of DN: immWrpTestCfg=testCfg
+---------------------------
+SaDoubleSingle: 66667
+SaFloatSingle: 5555.5
+SaInt32TSingle: 22
+SaInt64TSingle: 4444
+SaNameTSingle: Name
+SaStringSingle: 77777
+SaUint32TSingle: 111
+SaUint64TSingle: 3333
+
+#
\ No newline at end of file
diff --git a/src/immwrp/apitest/Makefile b/src/immwrp/apitest/Makefile
new file mode 100644
index 0000000..feb47a4
--- /dev/null
+++ b/src/immwrp/apitest/Makefile
@@ -0,0 +1,22 @@
+#      -*- OpenSAF  -*-
+#
+# (C) Copyright 2017 The OpenSAF Foundation
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+# under the GNU Lesser General Public License Version 2.1, February 1999.
+# The complete license can be accessed from the following location:
+# http://opensource.org/licenses/lgpl-license.php
+# See the Copying file included with the OpenSAF distribution for full
+# licensing terms.
+#
+# Author(s): Ericsson AB
+#
+
+all:
+       $(MAKE) -C ../../.. bin/immwrptest
+
+check:
+       $(MAKE) -C ../../.. bin/testimmwrp
+       ../../../bin/testimmwrp
diff --git a/src/immwrp/apitest/common.h b/src/immwrp/apitest/common.h
new file mode 100644
index 0000000..15aec69
--- /dev/null
+++ b/src/immwrp/apitest/common.h
@@ -0,0 +1,69 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#ifndef SRC_IMMWRP_TOOLS_COMMON_H_
+#define SRC_IMMWRP_TOOLS_COMMON_H_
+
+#include <string>
+#include <iostream>
+#include <map>
+#include <chrono>
+
+#include "immwrp/immom/om_handle.h"
+#include "immwrp/immom/om_search.h"
+#include "immwrp/immom/om_class_management.h"
+
+//>
+// For performent measurement
+//<
+#define CLOCK_START std::chrono::high_resolution_clock::now()
+#define CLOCK_END   std::chrono::high_resolution_clock::now()
+#define TIME_ELAPSED(start, end)                    {       \
+    std::chrono::duration<double> elapsed = end - start;    \
+    std::cout <<"-> " << __func__ << " @Elapsed time: " <<  \
+        elapsed.count() << std::endl;                       \
+  }
+
+//<
+
+using MapDb = std::map<std::string, SaImmValueTypeT>;
+
+// Multiple-value attributes map
+const MapDb mapdb = {
+  {"SaUint32TMultiple", SA_IMM_ATTR_SAUINT32T},
+  {"SaInt32TMultiple",  SA_IMM_ATTR_SAINT32T},
+  {"SaUint64TMultiple", SA_IMM_ATTR_SAUINT64T},
+  {"SaInt64TMultiple",  SA_IMM_ATTR_SAINT64T},
+  {"SaFloatMultiple",   SA_IMM_ATTR_SAFLOATT},
+  {"SaDoubleMultiple",  SA_IMM_ATTR_SADOUBLET},
+  {"SaStringMultiple",  SA_IMM_ATTR_SASTRINGT},
+  {"SaNameTMultiple",   SA_IMM_ATTR_SANAMET}
+};
+
+// Single-value attribute map
+const MapDb smapdb = {
+  {"SaUint32TSingle", SA_IMM_ATTR_SAUINT32T},
+  {"SaInt32TSingle",  SA_IMM_ATTR_SAINT32T},
+  {"SaUint64TSingle", SA_IMM_ATTR_SAUINT64T},
+  {"SaInt64TSingle",  SA_IMM_ATTR_SAINT64T},
+  {"SaFloatSingle",   SA_IMM_ATTR_SAFLOATT},
+  {"SaDoubleSingle",  SA_IMM_ATTR_SADOUBLET},
+  {"SaStringSingle",  SA_IMM_ATTR_SASTRINGT},
+  {"SaNameTSingle",   SA_IMM_ATTR_SANAMET}
+};
+
+#endif  // SRC_IMMWRP_TOOLS_COMMON_H_
diff --git a/src/immwrp/apitest/immwrp_test_classes.xml 
b/src/immwrp/apitest/immwrp_test_classes.xml
new file mode 100644
index 0000000..d68c235
--- /dev/null
+++ b/src/immwrp/apitest/immwrp_test_classes.xml
@@ -0,0 +1,227 @@
+<?xml version="1.0" encoding="utf-8"?>
+<imm:IMM-contents xmlns:imm="http://www.saforum.org/IMMSchema"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:noNamespaceSchemaLocation="SAI-AIS-IMM-XSD-A.02.13.xsd">
+       <class name="ImmWrpTestConfig">
+               <category>SA_CONFIG</category>
+               <rdn>
+                       <name>immWrpTestCfg</name>
+                       <type>SA_STRING_T</type>
+                       <category>SA_CONFIG</category>
+                       <flag>SA_INITIALIZED</flag>
+               </rdn>
+               <attr>
+                       <name>SaUint32TSingle</name>
+                       <type>SA_UINT32_T</type>
+                       <category>SA_CONFIG</category>
+                       <flag>SA_WRITABLE</flag>
+                       <default-value>123</default-value>
+               </attr>
+               <attr>
+                       <name>SaInt32TSingle</name>
+                       <type>SA_INT32_T</type>
+                       <category>SA_CONFIG</category>
+                       <flag>SA_WRITABLE</flag>
+                       <default-value>1234</default-value>
+               </attr>
+               <attr>
+                       <name>SaUint64TSingle</name>
+                       <type>SA_UINT64_T</type>
+                       <category>SA_CONFIG</category>
+                       <flag>SA_WRITABLE</flag>
+                       <default-value>12345</default-value>
+               </attr>
+               <attr>
+                       <name>SaInt64TSingle</name>
+                       <type>SA_INT64_T</type>
+                       <category>SA_CONFIG</category>
+                       <flag>SA_WRITABLE</flag>
+                       <default-value>123456</default-value>
+               </attr>
+               <attr>
+                       <name>SaFloatSingle</name>
+                       <type>SA_FLOAT_T</type>
+                       <category>SA_CONFIG</category>
+                       <flag>SA_WRITABLE</flag>
+                       <default-value>123456.7</default-value>
+               </attr>
+               <attr>
+                       <name>SaDoubleSingle</name>
+                       <type>SA_DOUBLE_T</type>
+                       <category>SA_CONFIG</category>
+                       <flag>SA_WRITABLE</flag>
+                       <default-value>123456.789</default-value>
+               </attr>
+               <attr>
+                       <name>SaStringSingle</name>
+                       <type>SA_STRING_T</type>
+                       <category>SA_CONFIG</category>
+                       <flag>SA_WRITABLE</flag>
+                       <default-value>saStringSingleV</default-value>
+               </attr>
+               <attr>
+                       <name>SaNameTSingle</name>
+                       <type>SA_NAME_T</type>
+                       <category>SA_CONFIG</category>
+                       <flag>SA_WRITABLE</flag>
+                       <default-value>saNameTSingleV</default-value>
+               </attr>
+       </class>
+<class name="ImmWrpTestMultipleConfig">
+               <category>SA_CONFIG</category>
+               <rdn>
+                       <name>immWrpTestMultipleCfg</name>
+                       <type>SA_STRING_T</type>
+                       <category>SA_CONFIG</category>
+                       <flag>SA_INITIALIZED</flag>
+               </rdn>
+               <attr>
+                       <name>SaUint32TMultiple</name>
+                       <type>SA_UINT32_T</type>
+                       <category>SA_CONFIG</category>
+                       <flag>SA_WRITABLE</flag>
+                       <flag>SA_MULTI_VALUE</flag>
+                       <flag>SA_NO_DUPLICATES</flag>
+                       <default-value>123</default-value>
+               </attr>
+               <attr>
+                       <name>SaInt32TMultiple</name>
+                       <type>SA_INT32_T</type>
+                       <category>SA_CONFIG</category>
+                       <flag>SA_INITIALIZED</flag>
+                       <flag>SA_WRITABLE</flag>
+                       <flag>SA_MULTI_VALUE</flag>
+                       <flag>SA_NO_DUPLICATES</flag>
+               </attr>
+               <attr>
+                       <name>SaUint64TMultiple</name>
+                       <type>SA_UINT64_T</type>
+                       <category>SA_CONFIG</category>
+                       <flag>SA_INITIALIZED</flag>
+                       <flag>SA_WRITABLE</flag>
+                       <flag>SA_MULTI_VALUE</flag>
+                       <flag>SA_NO_DUPLICATES</flag>
+               </attr>
+               <attr>
+                       <name>SaInt64TMultiple</name>
+                       <type>SA_INT64_T</type>
+                       <category>SA_CONFIG</category>
+                       <flag>SA_INITIALIZED</flag>
+                       <flag>SA_WRITABLE</flag>
+                       <flag>SA_MULTI_VALUE</flag>
+                       <flag>SA_NO_DUPLICATES</flag>
+               </attr>
+               <attr>
+                       <name>SaFloatMultiple</name>
+                       <type>SA_FLOAT_T</type>
+                       <category>SA_CONFIG</category>
+                       <flag>SA_INITIALIZED</flag>
+                       <flag>SA_WRITABLE</flag>
+                       <flag>SA_MULTI_VALUE</flag>
+                       <flag>SA_NO_DUPLICATES</flag>
+               </attr>
+               <attr>
+                       <name>SaDoubleMultiple</name>
+                       <type>SA_DOUBLE_T</type>
+                       <category>SA_CONFIG</category>
+                       <flag>SA_INITIALIZED</flag>
+                       <flag>SA_WRITABLE</flag>
+                       <flag>SA_MULTI_VALUE</flag>
+                       <flag>SA_NO_DUPLICATES</flag>
+               </attr>
+               <attr>
+                       <name>SaNameTMultiple</name>
+                       <type>SA_NAME_T</type>
+                       <category>SA_CONFIG</category>
+                       <flag>SA_WRITABLE</flag>
+                       <flag>SA_MULTI_VALUE</flag>
+                       <flag>SA_NO_DUPLICATES</flag>
+                       <flag>SA_INITIALIZED</flag>
+               </attr>
+               <attr>
+                       <name>SaStringMultiple</name>
+                       <type>SA_STRING_T</type>
+                       <category>SA_CONFIG</category>
+                       <flag>SA_WRITABLE</flag>
+                       <flag>SA_MULTI_VALUE</flag>
+                       <flag>SA_NO_DUPLICATES</flag>
+                       <default-value>Name1_1</default-value>
+               </attr>
+       </class>
+       <object class="ImmWrpTestConfig">
+               <dn>immWrpTestCfg=testCfg</dn>
+               <attr>
+                       <name>SaInt32TSingle</name>
+                       <value>22</value>
+               </attr>
+               <attr>
+                       <name>SaUint32TSingle</name>
+                       <value>111</value>
+               </attr>
+               <attr>
+                       <name>SaUint64TSingle</name>
+                       <value>3333</value>
+               </attr>
+               <attr>
+                       <name>SaInt64TSingle</name>
+                       <value>4444</value>
+               </attr>
+               <attr>
+                       <name>SaFloatSingle</name>
+                       <value>5555.5</value>
+               </attr>
+               <attr>
+                       <name>SaDoubleSingle</name>
+                       <value>66666.6</value>
+               </attr>
+               <attr>
+                       <name>SaNameTSingle</name>
+                       <value>Name</value>
+               </attr>
+               <attr>
+                       <name>SaStringSingle</name>
+                       <value>77777</value>
+               </attr>
+       </object>
+       <object class="ImmWrpTestMultipleConfig">
+               <dn>immWrpTestMultipleCfg=testMultipleCfg</dn>
+               <attr>
+                       <name>SaUint32TMultiple</name>
+                       <value>11</value>
+                       <value>112</value>
+               </attr>
+               <attr>
+                       <name>SaInt32TMultiple</name>
+                       <value>22</value>
+                       <value>223</value>
+               </attr>
+               <attr>
+                       <name>SaUint64TMultiple</name>
+                       <value>3333</value>
+                       <value>33334</value>
+               </attr>
+               <attr>
+                       <name>SaInt64TMultiple</name>
+                       <value>4444</value>
+                       <value>44445</value>
+               </attr>
+               <attr>
+                       <name>SaFloatMultiple</name>
+                       <value>5555.5</value>
+                       <value>55556.5</value>
+               </attr>
+               <attr>
+                       <name>SaDoubleMultiple</name>
+                       <value>66666.6</value>
+                       <value>666667.6</value>
+               </attr>
+               <attr>
+                       <name>SaNameTMultiple</name>
+                       <value>Name1</value>
+                       <value>Name2</value>
+               </attr>
+               <attr>
+                       <name>SaStringMultiple</name>
+                       <value>77777</value>
+                       <value>777778</value>
+               </attr>
+       </object>
+</imm:IMM-contents>
diff --git a/src/immwrp/apitest/immwrptest.cc b/src/immwrp/apitest/immwrptest.cc
new file mode 100644
index 0000000..810fb59
--- /dev/null
+++ b/src/immwrp/apitest/immwrptest.cc
@@ -0,0 +1,83 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#include <unistd.h>
+#include <iostream>
+
+#include "immwrp/apitest/omsearchnext.h"
+#include "immwrp/apitest/omclassmanagement.h"
+
+void usage(void) {
+  std::cout << "\nDESCRIPTION\n";
+  std::cout << "\tTest C++ IMM Wrapper\n";
+  std::cout << "\nOPTIONS\n";
+  std::cout << "\t-h \t This help\n";
+  std::cout << "\t-o \t Test IMM OM interfaces\n";
+  std::cout << "\t-i \t Test IMM OI interfaces\n";
+}
+
+int main(int argc, char *argv[]) {
+
+  while (1) {
+    int c = getopt(argc, argv, "?oih");
+    if (c == -1) {
+      break;
+    }
+
+    switch (c) {
+      case 'o':
+        std::cout << "@@ OBJECT SEARCH NEXT @@" << std::endl;
+        std::cout << "-- On Multiple Value Attribute Class --" << std::endl;
+        std::cout << "===============" << std::endl;
+        Test_OmSearchNext_OnMultipleValuesClass();
+        std::cout << std::endl;
+
+        std::cout << "-- On Single Value Attribute Class --" << std::endl;
+        std::cout << "===============" << std::endl;
+        Test_OmSearchNext_OnSingleValuesClass();
+        std::cout << std::endl;
+        std::cout << std::endl;
+
+        std::cout << "@@ CLASS DESCRIPTION GET @@" << std::endl;
+        std::cout << "-- On Multiple Value Attribute Class --" << std::endl;
+        std::cout << "===============" << std::endl;
+        Test_OmClassDescriptionGet_OnMultipleValueClass();
+        std::cout << std::endl;
+
+        std::cout << "-- On Single Value Attribute Class --" << std::endl;
+        std::cout << "===============" << std::endl;
+        Test_OmClassDescriptionGet_OnSingleValueClass();
+        std::cout << std::endl;
+        std::cout << std::endl;
+        break;
+
+      case 'i':
+        std::cout << "Test IMM OI interfaces\n";
+        break;
+
+      case 'h':
+        usage();
+        break;
+
+      case '?':
+      default:
+        fprintf(stderr, "Try -h for more information.\n");
+        break;
+    }
+  }
+  return 0;
+}
diff --git a/src/immwrp/apitest/omclassmanagement.cc 
b/src/immwrp/apitest/omclassmanagement.cc
new file mode 100644
index 0000000..b905e13
--- /dev/null
+++ b/src/immwrp/apitest/omclassmanagement.cc
@@ -0,0 +1,194 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#include "immwrp/apitest/omclassmanagement.h"
+
+#include <string>
+#include <iomanip>
+#include <vector>
+#include <map>
+
+#include "immwrp/apitest/common.h"
+#include "immwrp/immom/om_handle.h"
+#include "immwrp/immom/om_class_management.h"
+
+#include "base/saf_error.h"
+#include "base/osaf_extended_name.h"
+
+static SaVersionT immVersion = { 'A', 2, 11 };
+
+//------------------------------------------------------------------------------
+// Check GetSingle() value on all data types
+//------------------------------------------------------------------------------
+static void GetSingleValue(const immom::ImmOmClassDescriptionGet& obj,
+                           const std::string& name, bool isMultiple = true) {
+  const MapDb::const_iterator it =
+      (isMultiple == true) ? mapdb.find(name) : smapdb.find(name);
+
+  switch (it->second) {
+    case SA_IMM_ATTR_SAINT32T: {
+      auto output = obj.GetValue<SaInt32T>(name);
+      if (output == nullptr) return;
+      std::cout << name << ": " << *output << std::endl;
+      break;
+    }
+
+    case SA_IMM_ATTR_SAUINT32T: {
+      auto output = obj.GetValue<SaUint32T>(name);
+      if (output == nullptr) return;
+      std::cout << name << ": " << *output << std::endl;
+      break;
+    }
+
+    case SA_IMM_ATTR_SAINT64T: {
+      auto output = obj.GetValue<SaInt64T>(name);
+      if (output == nullptr) return;
+      std::cout << name << ": " << *output << std::endl;
+      break;
+    }
+
+    case SA_IMM_ATTR_SAUINT64T: {
+      auto output = obj.GetValue<SaUint64T>(name);
+      if (output == nullptr) return;
+      std::cout << name << ": " << *output << std::endl;
+      break;
+    }
+
+    case SA_IMM_ATTR_SATIMET: {
+      auto output = obj.GetValue<SaTimeT>(name);
+      if (output == nullptr) return;
+      std::cout << name << ": " << *output << std::endl;
+      break;
+    }
+
+    case SA_IMM_ATTR_SANAMET: {
+      auto output = obj.GetValue<SaNameT>(name);
+      if (output == nullptr) return;
+      std::string tmp = osaf_extended_name_borrow(output);
+      std::cout << name << ": " << tmp << std::endl;
+      break;
+    }
+
+    case SA_IMM_ATTR_SAFLOATT: {
+      auto output = obj.GetValue<SaFloatT>(name);
+      if (output == nullptr) return;
+      std::cout << name << ": " << std::setprecision(5) << *output << 
std::endl;
+      break;
+    }
+
+    case SA_IMM_ATTR_SADOUBLET: {
+     auto output = obj.GetValue<SaDoubleT>(name);
+     if (output == nullptr) return;
+     std::cout << name << ": " << std::setprecision(5) << *output << std::endl;
+     break;
+    }
+
+    case SA_IMM_ATTR_SASTRINGT: {
+     auto output = obj.GetValue<SaStringT>(name);
+     if (output == nullptr) return;
+     std::cout << name << ": " << *output << std::endl;
+     break;
+    }
+
+    default:
+      std::cerr << "Unknown type: " << name << std::endl;
+      break;
+  }
+}
+
+void Test_OmClassDescriptionGet_OnSingleValueClass() {
+  auto start = CLOCK_START;
+
+  immom::ImmOmInitialize omhandle(immVersion);
+  if (omhandle.InitHandle() == false) {
+    std::cerr << "OM handle: InitHandle() failed: " <<
+        saf_error(omhandle.GetAisErr()) << std::endl;
+    return;
+  }
+
+  immom::ImmOmFinalize omfinalize;
+  std::string classnames = "ImmWrpTestConfig";
+  immom::ImmOmClassDescriptionGet classgets(omhandle.GetHandle(), classnames);
+  if (classgets.GetClassDescription() == false) {
+    std::cerr << "GetClassDescription() failed: " <<
+        saf_error(classgets.GetAisErr()) << std::endl;
+    omfinalize.FinalizeHandle(omhandle.GetHandle());
+    return;
+  }
+
+  // Get initialized value of single-value attributes
+  SaImmClassCategoryT categorys = classgets.GetClassCategory();
+  std::cout << "Class ImmWrpTestConfig, Type: " << categorys << std::endl;
+  std::cout << "---------------------------" << std::endl;
+  for (const auto& attr : smapdb) {
+    GetSingleValue(classgets, attr.first, false);
+  }
+
+  immom::ImmOmClassDescriptionMemoryFree freemems(omhandle.GetHandle(),
+                                           classgets.GetResult().attrs);
+  if (freemems.FreeClassDescription() == false) {
+    std::cerr << "FreeClassDescription() failed: "
+              << saf_error(freemems.GetAisErr()) << std::endl;
+  }
+
+  omfinalize.FinalizeHandle(omhandle.GetHandle());
+
+  auto end = CLOCK_END;
+  TIME_ELAPSED(start, end);
+}
+
+void Test_OmClassDescriptionGet_OnMultipleValueClass() {
+  auto start = CLOCK_START;
+
+  immom::ImmOmInitialize omhandle(immVersion);
+  if (omhandle.InitHandle() == false) {
+    std::cerr << "OM handle: InitHandle() failed: "
+              << saf_error(omhandle.GetAisErr()) << std::endl;
+    return;
+  }
+
+  immom::ImmOmFinalize omfinalize;
+  std::string classname = "ImmWrpTestMultipleConfig";
+  immom::ImmOmClassDescriptionGet classget(omhandle.GetHandle(), classname);
+  if (classget.GetClassDescription() == false) {
+    std::cerr << "Class Description Get: GetClassDescription() failed: "
+              << saf_error(classget.GetAisErr()) << std::endl;
+    omfinalize.FinalizeHandle(omhandle.GetHandle());
+    return;
+  }
+
+  // Get initialized values of multiple-value attributes
+  SaImmClassCategoryT category = classget.GetClassCategory();
+  std::cout << "Class ImmWrpMultipleTestConfig, Type: "
+            << category << std::endl;
+  std::cout << "---------------------------" << std::endl;
+  for (const auto& attr : mapdb) {
+    GetSingleValue(classget, attr.first);
+  }
+
+  immom::ImmOmClassDescriptionMemoryFree freemem(omhandle.GetHandle(),
+                                          classget.GetResult().attrs);
+  if (freemem.FreeClassDescription() == false) {
+    std::cerr << "FreeClassDescription() failed: "
+              << saf_error(freemem.GetAisErr()) << std::endl;
+  }
+
+  omfinalize.FinalizeHandle(omhandle.GetHandle());
+
+  auto end = CLOCK_END;
+  TIME_ELAPSED(start, end);
+}
diff --git a/src/immwrp/apitest/omclassmanagement.h 
b/src/immwrp/apitest/omclassmanagement.h
new file mode 100644
index 0000000..896acff
--- /dev/null
+++ b/src/immwrp/apitest/omclassmanagement.h
@@ -0,0 +1,23 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+#ifndef SRC_IMMWRP_TOOLS_OMCLASSMANAGEMENT_H_
+#define SRC_IMMWRP_TOOLS_OMCLASSMANAGEMENT_H_
+
+void Test_OmClassDescriptionGet_OnSingleValueClass();
+void Test_OmClassDescriptionGet_OnMultipleValueClass();
+
+#endif  // SRC_IMMWRP_TOOLS_OMCLASSMANAGEMENT_H_
diff --git a/src/immwrp/apitest/omsearchnext.cc 
b/src/immwrp/apitest/omsearchnext.cc
new file mode 100644
index 0000000..f5f08bc
--- /dev/null
+++ b/src/immwrp/apitest/omsearchnext.cc
@@ -0,0 +1,311 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+#include "immwrp/apitest/omsearchnext.h"
+
+#include <unistd.h>
+#include <string>
+#include <iomanip>
+#include <iostream>
+#include <vector>
+
+#include "immwrp/apitest/common.h"
+#include "immwrp/immom/om_handle.h"
+#include "immwrp/immom/om_search.h"
+#include "base/saf_error.h"
+#include "base/osaf_extended_name.h"
+
+static SaVersionT immVersion = { 'A', 2, 11 };
+
+//------------------------------------------------------------------------------
+// Check GetMultiSingle() value on all data types
+//------------------------------------------------------------------------------
+static void GetMultipleValue(const immom::ImmOmSearchNext& obj,
+                             const std::string& name) {
+  const MapDb::const_iterator it = mapdb.find(name);
+  switch (it->second) {
+    case SA_IMM_ATTR_SAINT32T: {
+      auto output = obj.GetMultiValue<SaInt32T>(name);
+      std::cout << name << ": ";
+      for (const auto& v : output) {
+        std::cout << v << " ";
+      }
+      std::cout << std::endl;
+      break;
+    }
+
+    case SA_IMM_ATTR_SAUINT32T: {
+      auto output = obj.GetMultiValue<SaUint32T>(name);
+      std::cout << name << ": ";
+      for (const auto& v : output) {
+        std::cout << v << " ";
+      }
+      std::cout << std::endl;
+      break;
+    }
+
+    case SA_IMM_ATTR_SAINT64T: {
+      auto output = obj.GetMultiValue<SaInt64T>(name);
+      std::cout << name << ": ";
+      for (const auto& v : output) {
+        std::cout << v << " ";
+      }
+      std::cout << std::endl;
+      break;
+    }
+
+    case SA_IMM_ATTR_SAUINT64T: {
+      auto output = obj.GetMultiValue<SaUint64T>(name);
+      std::cout << name << ": ";
+      for (const auto& v : output) {
+        std::cout << v << " ";
+      }
+      std::cout << std::endl;
+      break;
+    }
+
+    case SA_IMM_ATTR_SATIMET: {
+      auto output = obj.GetMultiValue<SaTimeT>(name);
+      std::cout << name << ": ";
+      for (const auto& v : output) {
+        std::cout << v << " ";
+      }
+      std::cout << std::endl;
+      break;
+    }
+
+    case SA_IMM_ATTR_SANAMET: {
+      std::vector<SaNameT> output = obj.GetMultiValue<SaNameT>(name);
+      std::cout << name << ": ";
+      for (const auto& v : output) {
+        std::string tmp = osaf_extended_name_borrow(&v);
+        std::cout << tmp << " ";
+      }
+      std::cout << std::endl;
+      break;
+    }
+
+    case SA_IMM_ATTR_SAFLOATT: {
+      auto output = obj.GetMultiValue<SaFloatT>(name);
+      std::cout << name << ": ";
+      for (const auto& v : output) {
+        std::cout << v << " ";
+      }
+      std::cout << std::endl;
+      break;
+    }
+
+    case SA_IMM_ATTR_SADOUBLET: {
+     auto output = obj.GetMultiValue<SaDoubleT>(name);
+     std::cout << name << ": ";
+     for (const auto& v : output) {
+       std::cout << v << " ";
+     }
+     std::cout << std::endl;
+     break;
+    }
+
+    case SA_IMM_ATTR_SASTRINGT: {
+     auto output = obj.GetMultiValue<SaStringT>(name);
+     std::cout << name << ": ";
+     for (const auto& v : output) {
+       std::cout << v << " ";
+     }
+     std::cout << std::endl;
+     break;
+    }
+
+    default:
+      std::cerr << "Unknown type: " << name << std::endl;
+      break;
+  }
+}
+
+static void GetSingleValue(const immom::ImmOmSearchNext& obj,
+                           const std::string& name) {
+  const MapDb::const_iterator it = smapdb.find(name);
+  switch (it->second) {
+    case SA_IMM_ATTR_SAINT32T: {
+      auto output = obj.GetValue<SaInt32T>(name);
+      if (output == nullptr) return;
+      std::cout << name << ": " << *output << std::endl;
+      break;
+    }
+
+    case SA_IMM_ATTR_SAUINT32T: {
+      auto output = obj.GetValue<SaUint32T>(name);
+      if (output == nullptr) return;
+      std::cout << name << ": " << *output << std::endl;
+      break;
+    }
+
+    case SA_IMM_ATTR_SAINT64T: {
+      auto output = obj.GetValue<SaInt64T>(name);
+      if (output == nullptr) return;
+      std::cout << name << ": " << *output << std::endl;
+      break;
+    }
+
+    case SA_IMM_ATTR_SAUINT64T: {
+      auto output = obj.GetValue<SaUint64T>(name);
+      if (output == nullptr) return;
+      std::cout << name << ": " << *output << std::endl;
+      break;
+    }
+
+    case SA_IMM_ATTR_SATIMET: {
+      auto output = obj.GetValue<SaTimeT>(name);
+      if (output == nullptr) return;
+      std::cout << name << ": " << *output << std::endl;
+      break;
+    }
+
+    case SA_IMM_ATTR_SANAMET: {
+      auto output = obj.GetValue<SaNameT>(name);
+      if (output == nullptr) return;
+      std::string tmp = osaf_extended_name_borrow(output);
+      std::cout << name << ": " << tmp << std::endl;
+      break;
+    }
+
+    case SA_IMM_ATTR_SAFLOATT: {
+      auto output = obj.GetValue<SaFloatT>(name);
+      if (output == nullptr) return;
+      std::cout << name << ": " << std::setprecision(5) << *output << 
std::endl;
+      break;
+    }
+
+    case SA_IMM_ATTR_SADOUBLET: {
+     auto output = obj.GetValue<SaDoubleT>(name);
+     if (output == nullptr) return;
+     std::cout << name << ": " << std::setprecision(5) << *output << std::endl;
+     break;
+    }
+
+    case SA_IMM_ATTR_SASTRINGT: {
+     auto output = obj.GetValue<SaStringT>(name);
+     if (output == nullptr) return;
+     std::cout << name << ": " << *output << std::endl;
+     break;
+    }
+
+    default:
+      std::cerr << "Unknown type: " << name << std::endl;
+      break;
+  }
+}
+
+void Test_OmSearchNext_OnMultipleValuesClass() {
+  auto start = CLOCK_START;
+
+  immom::ImmOmInitialize omhandle(immVersion);
+  if (omhandle.InitHandle() == false) {
+    std::cerr << "OM handle: InitHandle() failed: "
+              << saf_error(omhandle.GetAisErr()) << std::endl;
+    return;
+  }
+
+  immom::ImmOmFinalize omfinalize;
+  immom::ImmOmSearchInit searchobj(omhandle.GetHandle());
+  const std::string attrName = "SaImmAttrClassName";
+  const char* className = "ImmWrpTestMultipleConfig";
+  //searchobj.SetScope(SA_IMM_SUBTREE);
+  searchobj.UseSubLevelScope();
+  //  searchobj.SetOpt(SA_IMM_SEARCH_ONE_ATTR | SA_IMM_SEARCH_GET_ALL_ATTR);
+  searchobj.UseAllAttrSearchOption();
+  //  searchobj.SetParam(attrName, SA_IMM_ATTR_SASTRINGT, &className);
+  searchobj.SetSearchParam<SaStringT>(attrName, 
const_cast<SaStringT*>(&className));
+  if (searchobj.InitHandle() == false) {
+    std::cerr << "Search Obj: InitHandle() failed: "
+              << saf_error(searchobj.GetAisErr()) << std::endl;
+    omfinalize.FinalizeHandle(omhandle.GetHandle());
+    return;
+  }
+
+  immom::ImmOmSearchNext searchnext(
+      omhandle.GetHandle(),
+      searchobj.GetHandle());
+  if (searchnext.SearchNext() == false) {
+    std::cerr << "SearchNext() failed: " <<
+        saf_error(searchobj.GetAisErr()) << std::endl;
+    omfinalize.FinalizeHandle(omhandle.GetHandle());
+    return;
+  }
+
+  // Get values of multiple-value attributes
+  std::string dn = searchnext.GetObjName();
+  std::cout << "Attribute value of DN: " << dn << std::endl;
+  std::cout << "---------------------------" << std::endl;
+  for (const auto& attr : mapdb) {
+    GetMultipleValue(searchnext, attr.first);
+  }
+
+  omfinalize.FinalizeHandle(omhandle.GetHandle());
+
+  auto end = CLOCK_END;
+  TIME_ELAPSED(start, end);
+}
+
+void Test_OmSearchNext_OnSingleValuesClass() {
+  auto start = CLOCK_START;
+
+  immom::ImmOmInitialize omhandle(immVersion);
+  if (omhandle.InitHandle() == false) {
+    std::cerr << "OM handle: InitHandle() failed: "
+              << saf_error(omhandle.GetAisErr()) << std::endl;
+    return;
+  }
+
+  immom::ImmOmFinalize omfinalize;
+  immom::ImmOmSearchInit searchobj(omhandle.GetHandle());
+  const char* classname = "ImmWrpTestConfig";
+  const std::string attrname = "SaImmAttrClassName";
+
+  // searchobj.SetScope(SA_IMM_SUBTREE);
+  searchobj.UseSubLevelScope();
+  //searchobj.SetOpt(SA_IMM_SEARCH_ONE_ATTR | SA_IMM_SEARCH_GET_ALL_ATTR);
+  searchobj.UseAllAttrSearchOption();
+  // searchobj.SetParam(s);
+  searchobj.SetSearchParam<SaStringT>(attrname, 
const_cast<char**>(&classname));
+  if (searchobj.InitHandle() == false) {
+    std::cerr << "Search Obj: InitHandle() failed: "
+              << saf_error(searchobj.GetAisErr()) << std::endl;
+    omfinalize.FinalizeHandle(omhandle.GetHandle());
+    return;
+  }
+
+  immom::ImmOmSearchNext searchnext(omhandle.GetHandle(),
+                                    searchobj.GetHandle());
+  if (searchnext.SearchNext() == false) {
+    std::cerr << "SearchNext() failed: "
+              << saf_error(searchnext.GetAisErr()) << std::endl;
+    omfinalize.FinalizeHandle(omhandle.GetHandle());
+    return;
+  }
+
+  // Get value of single-value attributes
+  std::string dn = searchnext.GetObjName();
+  std::cout << "Attribute value of DN: " << dn << std::endl;
+  std::cout << "---------------------------" << std::endl;
+  for (const auto& attr : smapdb) {
+    GetSingleValue(searchnext, attr.first);
+  }
+
+  omfinalize.FinalizeHandle(omhandle.GetHandle());
+
+  auto end = CLOCK_END;
+  TIME_ELAPSED(start, end);
+}
diff --git a/src/immwrp/apitest/omsearchnext.h 
b/src/immwrp/apitest/omsearchnext.h
new file mode 100644
index 0000000..f822afa
--- /dev/null
+++ b/src/immwrp/apitest/omsearchnext.h
@@ -0,0 +1,23 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+#ifndef SRC_IMMWRP_TOOLS_OMSEARCHNEXT_H_
+#define SRC_IMMWRP_TOOLS_OMSEARCHNEXT_H_
+
+void Test_OmSearchNext_OnSingleValuesClass();
+void Test_OmSearchNext_OnMultipleValuesClass();
+
+#endif  // SRC_IMMWRP_TOOLS_OMSEARCHNEXT_H_
diff --git a/src/immwrp/immom/Makefile b/src/immwrp/immom/Makefile
new file mode 100644
index 0000000..eb05255
--- /dev/null
+++ b/src/immwrp/immom/Makefile
@@ -0,0 +1,18 @@
+#      -*- OpenSAF  -*-
+#
+# (C) Copyright 2017 The OpenSAF Foundation
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+# under the GNU Lesser General Public License Version 2.1, February 1999.
+# The complete license can be accessed from the following location:
+# http://opensource.org/licenses/lgpl-license.php
+# See the Copying file included with the OpenSAF distribution for full
+# licensing terms.
+#
+# Author(s): Ericsson AB
+#
+
+all:
+       $(MAKE) -C ../../.. lib/libopensaf_immwrp.la
diff --git a/src/immwrp/immom/om_class_description_get.cc 
b/src/immwrp/immom/om_class_description_get.cc
new file mode 100644
index 0000000..0c8338e
--- /dev/null
+++ b/src/immwrp/immom/om_class_description_get.cc
@@ -0,0 +1,57 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#include "immwrp/immom/om_class_description_get.h"
+#include "base/time.h"
+
+namespace immom {
+
+//------------------------------------------------------------------------------
+// ImmOmClassDescriptionGet class
+//------------------------------------------------------------------------------
+ImmOmClassDescriptionGet::ImmOmClassDescriptionGet(
+    const SaImmHandleT& h, const std::string& className) {
+  handle_     = h;
+  class_name_ = className;
+}
+
+ImmOmClassDescriptionGet::~ImmOmClassDescriptionGet() {
+  handle_ = 0;
+}
+
+bool ImmOmClassDescriptionGet::GetClassDescription() {
+  bool ret = true;
+  base::Timer wtime(ctrl_.timeout);
+  char* classname = const_cast<char*>(class_name_.c_str());
+  while (wtime.is_timeout() == false) {
+    ais_err_ = saImmOmClassDescriptionGet_2(
+        handle_,
+        classname,
+        &result_.class_category,
+        &result_.attrs);
+    if (ais_err_ == SA_AIS_ERR_TRY_AGAIN) {
+      base::Sleep(ctrl_.interval);
+      continue;
+    }
+    break;
+  }
+
+  if (ais_err_ != SA_AIS_OK)  ret = false;
+  return ret;
+}
+
+}  // namespace immom
diff --git a/src/immwrp/immom/om_class_description_get.h 
b/src/immwrp/immom/om_class_description_get.h
new file mode 100644
index 0000000..b63eb6c
--- /dev/null
+++ b/src/immwrp/immom/om_class_description_get.h
@@ -0,0 +1,101 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#ifndef SRC_IMMWRP_IMMOM_OM_CLASS_DESCRIPTION_GET_H_
+#define SRC_IMMWRP_IMMOM_OM_CLASS_DESCRIPTION_GET_H_
+
+#include <string>
+#include <vector>
+
+#include "immwrp/immom/om_common.h"
+
+namespace immom {
+
+//------------------------------------------------------------------------------
+// Represent IMM C `saImmOmClassDescriptionGet_2()` function
+//------------------------------------------------------------------------------
+class ImmOmClassDescriptionGet : public ImmOmCommon {
+ public:
+  struct Result {
+    SaImmClassCategoryT class_category;
+    SaImmAttrDefinitionT_2** attrs;
+  };
+
+  explicit ImmOmClassDescriptionGet(const SaImmHandleT&, const std::string&);
+  ~ImmOmClassDescriptionGet();
+
+  // Perform actual C IMM API, then save the result to @result_
+  bool GetClassDescription();
+  // Offer a choice to get old result returned by corresspond C IMM API.
+  const Result& GetResult() const;
+  // Get the value of @attr from @result_
+  const SaImmClassCategoryT GetClassCategory() const;
+
+  //>
+  // Get value of IMM attribute @name
+  // typename @T is AIS type such as SaInt8T/SaFloatT/SaTimeT/SaStringT, etc.
+  //<
+  // Get value of single-value attribute.
+  template <typename T> T* GetValue(const std::string&) const;
+
+ private:
+  std::string class_name_;
+  Result result_;
+
+  DELETE_COPY_AND_MOVE_OPERATORS(ImmOmClassDescriptionGet);
+};
+
+inline const SaImmClassCategoryT
+ImmOmClassDescriptionGet::GetClassCategory() const {
+  return result_.class_category;
+}
+
+inline const ImmOmClassDescriptionGet::Result&
+ImmOmClassDescriptionGet::GetResult() const {
+  return result_;
+}
+
+template <typename T>
+T* ImmOmClassDescriptionGet::GetValue(const std::string& name) const {
+  unsigned i = 0;
+  bool found = false;
+  SaImmAttrDefinitionT_2* attr;
+
+  if (result_.attrs == nullptr) return nullptr;
+  // Cache `attrs[i]` in `attr` to improve performance
+  while ((attr = result_.attrs[i]) != nullptr) {
+    std::string str = std::string{attr->attrName};
+    // Continue if does not match or not single value type
+    if (name != str) {
+      i++;
+      continue;
+    }
+    found = true;
+    break;
+  }
+
+  if (found == true) {
+    if (attr->attrDefaultValue == nullptr) return nullptr;
+    return static_cast<T*>(attr->attrDefaultValue);
+  }
+
+  return nullptr;
+}
+
+}  // namespace immom
+
+#endif  // SRC_IMMWRP_IMMOM_OM_CLASS_DESCRIPTION_GET_H_
diff --git a/src/immwrp/immom/om_class_description_memory_free.cc 
b/src/immwrp/immom/om_class_description_memory_free.cc
new file mode 100644
index 0000000..8aba778
--- /dev/null
+++ b/src/immwrp/immom/om_class_description_memory_free.cc
@@ -0,0 +1,53 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#include "immwrp/immom/om_class_description_memory_free.h"
+#include "base/time.h"
+
+namespace immom {
+
+//------------------------------------------------------------------------------
+// ImmOmClassDescriptionMemoryFree class
+//------------------------------------------------------------------------------
+ImmOmClassDescriptionMemoryFree::ImmOmClassDescriptionMemoryFree(
+    const SaImmHandleT& h, SaImmAttrDefinitionT_2** attrs) {
+  handle_ = h;
+  attrs_  = attrs;
+}
+
+ImmOmClassDescriptionMemoryFree::~ImmOmClassDescriptionMemoryFree() {
+  handle_ = 0;
+  attrs_  = nullptr;
+}
+
+bool ImmOmClassDescriptionMemoryFree::FreeClassDescription() {
+  bool ret = true;
+  base::Timer wtime(ctrl_.timeout);
+  while (wtime.is_timeout() == false) {
+    ais_err_ = saImmOmClassDescriptionMemoryFree_2(handle_, attrs_);
+    if (ais_err_ == SA_AIS_ERR_TRY_AGAIN) {
+      base::Sleep(ctrl_.interval);
+      continue;
+    }
+    break;
+  }
+
+  if (ais_err_ != SA_AIS_OK)  ret = false;
+  return ret;
+}
+
+}  // namespace immom
diff --git a/src/immwrp/immom/om_class_description_memory_free.h 
b/src/immwrp/immom/om_class_description_memory_free.h
new file mode 100644
index 0000000..012b1e8
--- /dev/null
+++ b/src/immwrp/immom/om_class_description_memory_free.h
@@ -0,0 +1,48 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#ifndef SRC_IMMWRP_IMMOM_OM_CLASS_DESCRIPTION_MEMORY_FREE_H_
+#define SRC_IMMWRP_IMMOM_OM_CLASS_DESCRIPTION_MEMORY_FREE_H_
+
+#include <string>
+#include <vector>
+
+#include "immwrp/immom/om_common.h"
+
+namespace immom {
+
+//------------------------------------------------------------------------------
+// Represent IMM C `saImmOmClassDescriptionGet_2()` function
+//------------------------------------------------------------------------------
+class ImmOmClassDescriptionMemoryFree : public ImmOmCommon {
+ public:
+  explicit ImmOmClassDescriptionMemoryFree(const SaImmHandleT&,
+                                           SaImmAttrDefinitionT_2**);
+  ~ImmOmClassDescriptionMemoryFree();
+
+  // Perform actual C IMM API to free memory
+  bool FreeClassDescription();
+
+ private:
+  SaImmAttrDefinitionT_2** attrs_;
+
+  DELETE_COPY_AND_MOVE_OPERATORS(ImmOmClassDescriptionMemoryFree);
+};
+
+}  // namespace immom
+
+#endif  // SRC_IMMWRP_IMMOM_OM_CLASS_DESCRIPTION_MEMORY_FREE_H_
diff --git a/src/immwrp/immom/om_class_management.h 
b/src/immwrp/immom/om_class_management.h
new file mode 100644
index 0000000..7821228
--- /dev/null
+++ b/src/immwrp/immom/om_class_management.h
@@ -0,0 +1,24 @@
+/*      -*- OpenSAF  -*-
+ *
+ * Copyright Ericsson AB 2017 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#ifndef SRC_IMMWRP_IMMOM_OM_CLASS_MANAGEMENT_H_
+#define SRC_IMMWRP_IMMOM_OM_CLASS_MANAGEMENT_H_
+
+#include "immwrp/immom/om_class_description_get.h"
+#include "immwrp/immom/om_class_description_memory_free.h"
+
+#endif  // SRC_IMMWRP_IMMOM_OM_CLASS_MANAGEMENT_H_
diff --git a/src/immwrp/immom/om_common.h b/src/immwrp/immom/om_common.h
new file mode 100644
index 0000000..8cd2794
--- /dev/null
+++ b/src/immwrp/immom/om_common.h
@@ -0,0 +1,77 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#ifndef SRC_IMMWRP_IMMOM_OM_COMMON_H_
+#define SRC_IMMWRP_IMMOM_OM_COMMON_H_
+
+#include <string>
+#include "osaf/saf/saAis.h"
+#include "imm/saf/saImmOm.h"
+#include "base/time.h"
+
+// Default wait time for retries (30s)
+const uint64_t kWaitTime = 30*1000;
+
+//>
+// To control try again in OM IMM wrapper APIs
+// And can be reused by OI IMM wrapper APIs too.
+//
+// @interval: sleep time b/w retry.
+// @timeout : maximum time for retries.
+//<
+class RetryControl {
+ public:
+  RetryControl() : timeout{kWaitTime} {
+    interval = base::kOneHundredMilliseconds;
+  }
+
+  RetryControl& operator=(const RetryControl& info) {
+    interval = info.interval;
+    timeout = info.timeout;
+    return *this;
+  }
+
+ public:
+  timespec interval;
+  uint64_t timeout;
+};
+
+//>
+// Common class for all concrete IMM OM classes
+// NOTE: should move this class into its own separated file
+//<
+class ImmOmCommon {
+ public:
+  ImmOmCommon() {}
+  ~ImmOmCommon() {}
+
+  // Set information to deal with SA_AIS_ERR_TRY_AGAIN error code.
+  // If want to change default control setting, provide your interest one.
+  void SetRetryInfo(const RetryControl& info) {
+    ctrl_ = info;
+  }
+
+  // Get AIS error code which has been saved before.
+  SaAisErrorT GetAisErr() { return ais_err_; }
+
+ protected:
+  SaAisErrorT ais_err_;
+  RetryControl ctrl_;
+  SaImmHandleT handle_;
+};
+
+#endif  // SRC_IMMWRP_IMMOM_OM_COMMON_H_
diff --git a/src/immwrp/immom/om_finalize.cc b/src/immwrp/immom/om_finalize.cc
new file mode 100644
index 0000000..ce36761
--- /dev/null
+++ b/src/immwrp/immom/om_finalize.cc
@@ -0,0 +1,46 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#include "immwrp/immom/om_finalize.h"
+
+namespace immom {
+
+//------------------------------------------------------------------------------
+// ImmOmInitialize class
+//------------------------------------------------------------------------------
+bool ImmOmFinalize::FinalizeHandle(const SaImmHandleT& h) {
+  bool ret = false;
+
+  base::Timer wtime(ctrl_.timeout);
+  while (wtime.is_timeout() == false) {
+    ais_err_ = saImmOmFinalize(h);
+    if (ais_err_ == SA_AIS_ERR_TRY_AGAIN) {
+      base::Sleep(ctrl_.interval);
+      continue;
+    }
+    break;
+  }
+
+  if (ais_err_ == SA_AIS_OK) {
+    handle_ = 0;
+    ret = true;
+  }
+
+  return ret;
+}
+
+}  // namespace immom
diff --git a/src/immwrp/immom/om_finalize.h b/src/immwrp/immom/om_finalize.h
new file mode 100644
index 0000000..76352d0
--- /dev/null
+++ b/src/immwrp/immom/om_finalize.h
@@ -0,0 +1,37 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#ifndef SRC_IMMWRP_IMMOM_OM_FINALIZE_H_
+#define SRC_IMMWRP_IMMOM_OM_FINALIZE_H_
+
+#include "immwrp/immom/om_common.h"
+
+namespace immom {
+//>
+// Represent the C function `saImmOmFinalize`
+//<
+class ImmOmFinalize : public ImmOmCommon {
+ public:
+  ImmOmFinalize() { }
+  ~ImmOmFinalize() { }
+
+  // Finalize @h from IMM
+  bool FinalizeHandle(const SaImmHandleT& h);
+};
+
+}  // namespace immom
+#endif  // SRC_IMMWRP_IMMOM_OM_FINALIZE_H_
diff --git a/src/immwrp/immom/om_handle.h b/src/immwrp/immom/om_handle.h
new file mode 100644
index 0000000..28b163c
--- /dev/null
+++ b/src/immwrp/immom/om_handle.h
@@ -0,0 +1,24 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#ifndef SRC_IMMWRP_IMMOM_OM_HANDLE_H_
+#define SRC_IMMWRP_IMMOM_OM_HANDLE_H_
+
+#include "immwrp/immom/om_initialize.h"
+#include "immwrp/immom/om_finalize.h"
+
+#endif  // SRC_IMMWRP_IMMOM_OM_HANDLE_H_
diff --git a/src/immwrp/immom/om_initialize.cc 
b/src/immwrp/immom/om_initialize.cc
new file mode 100644
index 0000000..e129e3d
--- /dev/null
+++ b/src/immwrp/immom/om_initialize.cc
@@ -0,0 +1,57 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#include "immwrp/immom/om_initialize.h"
+
+namespace immom {
+
+//------------------------------------------------------------------------------
+// ImmOmInitialize class
+//------------------------------------------------------------------------------
+ImmOmInitialize::ImmOmInitialize(
+    const SaVersionT& ver, const SaImmCallbacksT* cb)
+    : ImmOmCommon() {
+  cb_ = cb;
+  ver_ = ver;
+  handle_ = 0;
+}
+
+ImmOmInitialize::~ImmOmInitialize() {
+  // Do nothing
+}
+
+// Initialize @handle_ from IMM
+bool ImmOmInitialize::InitHandle() {
+  bool ret = true;
+  SaVersionT localVer = ver_;
+  base::Timer wtime(ctrl_.timeout);
+
+  while (wtime.is_timeout() == false) {
+    ais_err_ = saImmOmInitialize(&handle_, cb_, &localVer);
+    if (ais_err_ == SA_AIS_ERR_TRY_AGAIN) {
+      base::Sleep(ctrl_.interval);
+      continue;
+    }
+    break;
+  }
+
+  if (ais_err_ != SA_AIS_OK) ret = false;
+
+  return ret;
+}
+
+}  // namespace immom
diff --git a/src/immwrp/immom/om_initialize.h b/src/immwrp/immom/om_initialize.h
new file mode 100644
index 0000000..3eddab7
--- /dev/null
+++ b/src/immwrp/immom/om_initialize.h
@@ -0,0 +1,46 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#ifndef SRC_IMMWRP_IMMOM_OM_INITIALIZE_H_
+#define SRC_IMMWRP_IMMOM_OM_INITIALIZE_H_
+
+#include "imm/saf/saImmOm.h"
+#include "immwrp/immom/om_common.h"
+
+namespace immom {
+//>
+// Represent the C function `saImmOmInitialize`
+//<
+class ImmOmInitialize : public ImmOmCommon {
+ public:
+  explicit ImmOmInitialize(const SaVersionT& ver,
+                           const SaImmCallbacksT* cb = nullptr);
+  ~ImmOmInitialize();
+
+  // Initialize @handle_ from IMM
+  bool InitHandle();
+  // Get @handle_
+  SaImmHandleT GetHandle() const { return handle_; }
+
+ private:
+  const SaImmCallbacksT* cb_;
+  SaVersionT ver_;
+};
+
+}  // namespace immom
+
+#endif  // SRC_IMMWRP_IMMOM_OM_INITIALIZE_H_
diff --git a/src/immwrp/immom/om_search.h b/src/immwrp/immom/om_search.h
new file mode 100644
index 0000000..3a4c30a
--- /dev/null
+++ b/src/immwrp/immom/om_search.h
@@ -0,0 +1,25 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#ifndef SRC_IMMWRP_IMMOM_OM_SEARCH_H_
+#define SRC_IMMWRP_IMMOM_OM_SEARCH_H_
+
+#include "immwrp/immom/om_search_init.h"
+#include "immwrp/immom/om_search_finalize.h"
+#include "immwrp/immom/om_search_next.h"
+
+#endif  // SRC_IMMWRP_IMMOM_OM_SEARCH_H_
diff --git a/src/immwrp/immom/om_search_finalize.cc 
b/src/immwrp/immom/om_search_finalize.cc
new file mode 100644
index 0000000..8826c5d
--- /dev/null
+++ b/src/immwrp/immom/om_search_finalize.cc
@@ -0,0 +1,46 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#include "immwrp/immom/om_search_finalize.h"
+#include "base/time.h"
+
+namespace immom {
+
+//------------------------------------------------------------------------------
+// Represent IMM C `saImmOmSearchFinalize()` function
+//------------------------------------------------------------------------------
+bool ImmOmSearchFinalize::FinalizeHandle(const SaImmSearchHandleT& h) {
+  bool ret = true;
+
+  base::Timer wtime(ctrl_.timeout);
+  while (wtime.is_timeout() == false) {
+    ais_err_ = saImmOmSearchFinalize(h);
+    if (ais_err_ == SA_AIS_ERR_TRY_AGAIN) {
+      base::Sleep(ctrl_.interval);
+      continue;
+    }
+    break;
+  }
+
+  if (ais_err_ != SA_AIS_OK) {
+    ret = false;
+  }
+
+  return ret;
+}
+
+}  // namespace immom
diff --git a/src/immwrp/immom/om_search_finalize.h 
b/src/immwrp/immom/om_search_finalize.h
new file mode 100644
index 0000000..622f6ee
--- /dev/null
+++ b/src/immwrp/immom/om_search_finalize.h
@@ -0,0 +1,41 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#ifndef SRC_IMMWRP_IMMOM_OM_SEARCH_FINALIZE_H_
+#define SRC_IMMWRP_IMMOM_OM_SEARCH_FINALIZE_H_
+
+#include "immwrp/immom/om_common.h"
+
+namespace immom {
+
+//------------------------------------------------------------------------------
+// Represent IMM C `saImmOmSearchFinalize()` function
+//------------------------------------------------------------------------------
+class ImmOmSearchFinalize : public ImmOmCommon {
+ public:
+  ImmOmSearchFinalize() { }
+  ~ImmOmSearchFinalize() { }
+
+  bool FinalizeHandle(const SaImmSearchHandleT&);
+
+ private:
+  DELETE_COPY_AND_MOVE_OPERATORS(ImmOmSearchFinalize);
+};
+
+}  // namespace immom
+
+#endif  // SRC_IMMWRP_IMMOM_OM_SEARCH_FINALIZE_H_
diff --git a/src/immwrp/immom/om_search_init.cc 
b/src/immwrp/immom/om_search_init.cc
new file mode 100644
index 0000000..e2d02e1
--- /dev/null
+++ b/src/immwrp/immom/om_search_init.cc
@@ -0,0 +1,90 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#include "immwrp/immom/om_search_init.h"
+#include <memory>
+#include "base/osaf_extended_name.h"
+
+namespace immom {
+
+//------------------------------------------------------------------------------
+// ImmOmSearchInit class
+//------------------------------------------------------------------------------
+ImmOmSearchInit::ImmOmSearchInit(const SaImmHandleT& h) : root_{""}, opt_{0} {
+      attrs_.clear();
+      ResetSearchParam();
+      handle_ = h;
+      s_handle_ = 0;
+}
+
+ImmOmSearchInit::~ImmOmSearchInit() {
+  opt_   = 0;
+  handle_ = 0;
+  attrs_.clear();
+  ResetSearchParam();
+}
+
+// Initialize @s_handle_ from IMM
+bool ImmOmSearchInit::InitHandle() {
+  bool ret = true;
+  SaNameT root;
+  SaImmAttrNameT *attrNames = nullptr;
+
+  // Form `root`
+  if (root_.empty() != true) {
+    osaf_extended_name_lend(root_.c_str(), &root);
+  }
+
+  // Form attributeNames
+  if (attrs_.empty() != true) {
+    unsigned i = 0;
+    size_t size = attrs_.size();
+    attrNames = new SaImmAttrNameT[size+1];
+    for (const auto& a : attrs_) {
+      attrNames[i] = const_cast<char *>(a.c_str());
+      i++;
+    }
+    attrNames[i] = nullptr;
+  }
+
+  // Acquire @s_handle_ from IMM
+  base::Timer wtime(ctrl_.timeout);
+  while (wtime.is_timeout() == false) {
+    ais_err_ = saImmOmSearchInitialize_2(
+        handle_,
+        (root_.empty() == true)? nullptr: &root,
+        scope_,
+        opt_,
+        &search_param_,
+        attrNames,
+        &s_handle_);
+    if (ais_err_ == SA_AIS_ERR_TRY_AGAIN) {
+      base::Sleep(ctrl_.interval);
+      continue;
+    }
+    break;
+  }
+
+  if (attrs_.empty() != true && attrNames != nullptr) {
+    delete[] attrNames;
+  }
+
+  if (ais_err_ != SA_AIS_OK) ret = false;
+  return ret;
+}
+
+}  // namespace immom
diff --git a/src/immwrp/immom/om_search_init.h 
b/src/immwrp/immom/om_search_init.h
new file mode 100644
index 0000000..bafcba6
--- /dev/null
+++ b/src/immwrp/immom/om_search_init.h
@@ -0,0 +1,160 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#ifndef SRC_IMMWRP_IMMOM_OM_SEARCH_INIT_H_
+#define SRC_IMMWRP_IMMOM_OM_SEARCH_INIT_H_
+
+#include <string.h>
+#include <string>
+#include <vector>
+
+#include "immwrp/immom/om_common.h"
+
+namespace immom {
+
+//------------------------------------------------------------------------------
+// Represent IMM C function `saImmOmSearchInitialize_2()`
+//------------------------------------------------------------------------------
+class ImmOmSearchInit : public ImmOmCommon {
+ public:
+  using VectorString = std::vector<std::string>;
+
+  explicit ImmOmSearchInit(const SaImmHandleT&);
+  ~ImmOmSearchInit();
+
+  //>
+  // Methods are used to collect necessary info before calling @InitHandle()
+  //<
+
+  // Set info for @rootName
+  ImmOmSearchInit& SetRoot(const std::string&);
+
+  // Set info for @scope
+  ImmOmSearchInit& UseSubLevelScope();
+  ImmOmSearchInit& UseSubTreeScope();
+
+  // Set info for @searchOptions
+  ImmOmSearchInit& UseAllAttrSearchOption();
+  ImmOmSearchInit& UseNoAttrSearchOption();
+
+  // Set info for @a
+  ImmOmSearchInit& UseSomeAttrSearchOption(const std::string&);
+  ImmOmSearchInit& UseSomeAttrSearchOption(const VectorString&);
+
+  // Set @searchParam in case of using @UseSomeAttrSearchOption
+  template <typename T> ImmOmSearchInit& SetSearchParam(
+      const std::string&, T*);
+
+  // Initialize @s_handle_ from IMM
+  bool InitHandle();
+  // Get @s_handle_
+  SaImmSearchHandleT GetHandle() const { return s_handle_; }
+
+ private:
+  // Set default value to @search_param_
+  void ResetSearchParam();
+  std::string root_;
+  SaImmScopeT scope_;
+  SaImmSearchOptionsT opt_;
+  SaImmSearchParametersT_2 search_param_;
+  std::vector<std::string> attrs_;
+  SaImmSearchHandleT s_handle_;
+
+  DELETE_COPY_AND_MOVE_OPERATORS(ImmOmSearchInit);
+};
+
+inline void ImmOmSearchInit::ResetSearchParam() {
+  search_param_.searchOneAttr.attrName = nullptr;
+  search_param_.searchOneAttr.attrValueType = SA_IMM_ATTR_SAINT32T;
+  search_param_.searchOneAttr.attrValue = nullptr;
+}
+
+inline ImmOmSearchInit& ImmOmSearchInit::SetRoot(const std::string& root) {
+  root_ = root;
+  return *this;
+}
+
+// Set info for @scope
+inline ImmOmSearchInit& ImmOmSearchInit::UseSubLevelScope() {
+  scope_ = SA_IMM_SUBLEVEL;
+  return *this;
+}
+
+inline ImmOmSearchInit& ImmOmSearchInit::UseSubTreeScope() {
+  scope_ = SA_IMM_SUBTREE;
+  return *this;
+}
+
+// Set info for @searchOptions, @searchParam and @attributeNames
+inline ImmOmSearchInit& ImmOmSearchInit::UseAllAttrSearchOption() {
+  opt_ = SA_IMM_SEARCH_ONE_ATTR | SA_IMM_SEARCH_GET_ALL_ATTR;
+  return *this;
+}
+
+inline ImmOmSearchInit& ImmOmSearchInit::UseNoAttrSearchOption() {
+  opt_ = SA_IMM_SEARCH_ONE_ATTR | SA_IMM_SEARCH_GET_NO_ATTR;
+  return *this;
+}
+
+inline ImmOmSearchInit& ImmOmSearchInit::UseSomeAttrSearchOption(
+    const std::string& attrname) {
+  opt_ = SA_IMM_SEARCH_ONE_ATTR | SA_IMM_SEARCH_GET_SOME_ATTR;
+  attrs_.push_back(attrname);
+  return *this;
+}
+
+inline ImmOmSearchInit& ImmOmSearchInit::UseSomeAttrSearchOption(
+    const VectorString& attrnames) {
+  opt_ = SA_IMM_SEARCH_ONE_ATTR | SA_IMM_SEARCH_GET_SOME_ATTR;
+  attrs_ = attrnames;
+  return *this;
+}
+
+template <typename T>
+ImmOmSearchInit& ImmOmSearchInit::SetSearchParam(
+    const std::string& attrname, T* value) {
+  search_param_.searchOneAttr.attrName = const_cast<char*>(attrname.c_str());
+  search_param_.searchOneAttr.attrValue = value;
+
+  // Depend on @T, will have different @attrValueType
+  if (std::is_same<T, SaInt32T>::value) {
+    search_param_.searchOneAttr.attrValueType = SA_IMM_ATTR_SAINT32T;
+  } else if (std::is_same<T, SaUint32T>::value) {
+    search_param_.searchOneAttr.attrValueType = SA_IMM_ATTR_SAUINT32T;
+  } else if (std::is_same<T, SaInt64T>::value) {
+    search_param_.searchOneAttr.attrValueType = SA_IMM_ATTR_SAINT64T;
+  } else if (std::is_same<T, SaUint64T>::value) {
+    search_param_.searchOneAttr.attrValueType = SA_IMM_ATTR_SAUINT64T;
+  } else if (std::is_same<T, SaNameT>::value) {
+    search_param_.searchOneAttr.attrValueType = SA_IMM_ATTR_SANAMET;
+  } else if (std::is_same<T, SaFloatT>::value) {
+    search_param_.searchOneAttr.attrValueType = SA_IMM_ATTR_SAFLOATT;
+  } else if (std::is_same<T, SaDoubleT>::value) {
+    search_param_.searchOneAttr.attrValueType = SA_IMM_ATTR_SADOUBLET;
+  } else if (std::is_same<T, SaStringT>::value) {
+    search_param_.searchOneAttr.attrValueType = SA_IMM_ATTR_SASTRINGT;
+  } else if (std::is_same<T, SaAnyT>::value) {
+    search_param_.searchOneAttr.attrValueType = SA_IMM_ATTR_SAANYT;
+  } else {
+    osaf_abort(0);
+  }
+  return *this;
+}
+
+}  // namespace immom
+
+#endif  // SRC_IMMWRP_IMMOM_OM_SEARCH_INIT_H_
diff --git a/src/immwrp/immom/om_search_next.cc 
b/src/immwrp/immom/om_search_next.cc
new file mode 100644
index 0000000..40749d3
--- /dev/null
+++ b/src/immwrp/immom/om_search_next.cc
@@ -0,0 +1,61 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#include "immwrp/immom/om_search_next.h"
+#include "base/osaf_extended_name.h"
+#include "base/time.h"
+
+namespace immom {
+
+//------------------------------------------------------------------------------
+// ImmOmSearchNext class
+//------------------------------------------------------------------------------
+ImmOmSearchNext::ImmOmSearchNext(const SaImmHandleT& h,
+                                 const SaImmSearchHandleT& sh) {
+  handle_ = h;
+  s_handle_ = sh;
+}
+
+ImmOmSearchNext::~ImmOmSearchNext() {
+  handle_ = 0;
+  s_handle_ = 0;
+}
+
+bool ImmOmSearchNext::SearchNext() {
+  bool ret = true;
+  SaNameT dn;
+  base::Timer wtime(ctrl_.timeout);
+  while (wtime.is_timeout() == false) {
+    ais_err_ = saImmOmSearchNext_2(s_handle_, &dn, &result_.attrs);
+    if (ais_err_ == SA_AIS_ERR_TRY_AGAIN) {
+      base::Sleep(ctrl_.interval);
+      continue;
+    }
+    break;
+  }
+
+  if (ais_err_ != SA_AIS_OK) {
+    ret = false;
+    return ret;
+  }
+
+  result_.dn = osaf_extended_name_borrow(&dn);
+
+  return ret;
+}
+
+}  // namespace immom
diff --git a/src/immwrp/immom/om_search_next.h 
b/src/immwrp/immom/om_search_next.h
new file mode 100644
index 0000000..5913f10
--- /dev/null
+++ b/src/immwrp/immom/om_search_next.h
@@ -0,0 +1,138 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2017 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#ifndef SRC_IMMWRP_IMMOM_OM_SEARCH_NEXT_H_
+#define SRC_IMMWRP_IMMOM_OM_SEARCH_NEXT_H_
+
+#include <string>
+#include <vector>
+
+#include "immwrp/immom/om_common.h"
+
+namespace immom {
+
+//------------------------------------------------------------------------------
+// Represent IMM C `saImmOmSearchNext_2()` function
+//------------------------------------------------------------------------------
+class ImmOmSearchNext : public ImmOmCommon {
+ public:
+  struct Result {
+    std::string dn;
+    SaImmAttrValuesT_2** attrs;
+  };
+
+  explicit ImmOmSearchNext(const SaImmHandleT&, const SaImmSearchHandleT&);
+  ~ImmOmSearchNext();
+
+  // Perform actual C IMM API, then save the result to @result_
+  bool SearchNext();
+
+  // Offer a choice to get old result returned by corresspond C IMM API.
+  const Result& GetResult() const;
+
+  // Get the value of @attr from @result_
+  const std::string& GetObjName() const;
+  //>
+  // Get value of IMM attribute @name
+  // typename @T is AIS type such as SaInt8T/SaFloatT/SaTimeT/SaStringT, etc.
+  //<
+  // Get value of single-value attribute.
+  template <typename T> T* GetValue(const std::string&) const;
+  // Get values of multiple-value attribute
+  template <typename T> std::vector<T> GetMultiValue(const std::string&) const;
+
+ private:
+  // Search Handle
+  SaImmSearchHandleT s_handle_;
+  Result result_;
+
+  DELETE_COPY_AND_MOVE_OPERATORS(ImmOmSearchNext);
+};
+
+inline const ImmOmSearchNext::Result& ImmOmSearchNext::GetResult() const {
+  return result_;
+}
+
+inline const std::string& ImmOmSearchNext::GetObjName() const {
+  return result_.dn;
+}
+
+template <typename T>
+T* ImmOmSearchNext::GetValue(const std::string& name) const {
+  unsigned i = 0;
+  bool found = false;
+  SaImmAttrValuesT_2* attr;
+
+  if (result_.attrs == nullptr) return nullptr;
+  // Cache attrs[i] in attr to improve performance
+  while ((attr = result_.attrs[i]) != nullptr) {
+    std::string str = std::string{attr->attrName};
+    // Continue if does not match or not single value type
+    if (name != str || attr->attrValuesNumber != 1) {
+      i++;
+      continue;
+    }
+    found = true;
+    break;
+  }
+
+  if (found == true) {
+    if (attr->attrValues == nullptr) return nullptr;
+    return static_cast<T*>(attr->attrValues[0]);
+  }
+
+  return nullptr;
+}
+
+template <typename T>
+std::vector<T> ImmOmSearchNext::GetMultiValue(const std::string& name) const {
+  unsigned i = 0;
+  bool found = false;
+  SaImmAttrValuesT_2* attr;
+  std::vector<T> out{};
+
+  if (result_.attrs == nullptr) return out;
+
+  while ((attr = result_.attrs[i]) != nullptr) {
+    std::string str = std::string{attr->attrName};
+    // Continue if does not match or not single value type
+    if (name != str) {
+      i++;
+      continue;
+    }
+    found = true;
+    break;
+  }
+
+  if (found == true) {
+    unsigned ii = 0;
+    if (attr->attrValues == nullptr) return out;
+    // Cache attrValues[ii] in `data` to improve performance
+    void* data;
+    while ((data = attr->attrValues[ii]) != nullptr) {
+      T aValue = *(static_cast<T*>(data));
+      out.push_back(aValue);
+      ii++;
+    }
+  }
+
+  return out;
+}
+
+}  // namespace immom
+
+#endif  // SRC_IMMWRP_IMMOM_OM_SEARCH_NEXT_H_
diff --git a/src/immwrp/tests/Makefile b/src/immwrp/tests/Makefile
new file mode 100644
index 0000000..320d4d1
--- /dev/null
+++ b/src/immwrp/tests/Makefile
@@ -0,0 +1,19 @@
+#      -*- OpenSAF  -*-
+#
+# (C) Copyright 2017 The OpenSAF Foundation
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+# under the GNU Lesser General Public License Version 2.1, February 1999.
+# The complete license can be accessed from the following location:
+# http://opensource.org/licenses/lgpl-license.php
+# See the Copying file included with the OpenSAF distribution for full
+# licensing terms.
+#
+# Author(s): Ericsson AB
+#
+
+check:
+       $(MAKE) -C ../../.. bin/testimmwrp
+       ../../../bin/testimmwrp
diff --git a/src/immwrp/tests/common.h b/src/immwrp/tests/common.h
new file mode 100644
index 0000000..83d5cef
--- /dev/null
+++ b/src/immwrp/tests/common.h
@@ -0,0 +1,40 @@
+/*      -*- OpenSAF  -*-
+ *
+ * Copyright Ericsson AB 2017 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#ifndef SRC_IMMWRP_TESTS_COMMON_H_
+#define SRC_IMMWRP_TESTS_COMMON_H_
+
+// Convert input type to string, used for attribute name
+// e.g: AttrName(SaInT32T) --> will get "S_SaInt32T"
+#define ToString(input)            (#input)
+#define AttrName(type)             (ToString(S_##type))
+
+// Get attribute value for input type
+// e.g: AttrValue(SaInt32T) --> will get `v_SaInt32T`
+#define AttrValue(type)            (v_##type)
+#define AttrValue1(type)           (v_##type##_1)
+
+// Get corresponding `SaImmAttrDefinitionT_2` value
+// e.g: CfgAttrDefine(SaUint32T) --> will get `cfg_attr_SaUint32T`
+#define CfgAttrDefine(type)        (cfg_attr_##type)
+#define McfgAttrDefine(type)       (m_cfg_attr_##type)
+
+// Get corresponding SaImmAttrValueT** for input `type`
+// e.g: mValue(SaInt32T) --> will get `m_SaInt32T`
+#define mValue(type)    (m_##type)
+
+#endif  // SRC_IMMWRP_TESTS_COMMON_H__
diff --git a/src/immwrp/tests/omclassmanagement_test.cc 
b/src/immwrp/tests/omclassmanagement_test.cc
new file mode 100644
index 0000000..fe5f06b
--- /dev/null
+++ b/src/immwrp/tests/omclassmanagement_test.cc
@@ -0,0 +1,204 @@
+/*      -*- OpenSAF  -*-
+ *
+ * Copyright Ericsson AB 2017 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#include "gtest/gtest.h"
+
+#define protected public
+#define private public
+
+#include <stdlib.h>
+#include <string>
+#include <vector>
+#include "immwrp/immom/om_class_description_get.h"
+#include "osaf/saf/saAis.h"
+#include "imm/saf/saImm.h"
+#include "base/osaf_extended_name.h"
+#include "immwrp/tests/common.h"
+
+//>
+// Test Data
+//<
+
+// Values of attributes that cover all data types
+// NOTE: variable names MUST follow the rule `v_TYPE`
+static SaInt32T  v_SaInt32T   = 11;
+static SaUint32T v_SaUint32T  = 22;
+static SaInt64T  v_SaInt64T   = 333;
+static SaUint64T v_SaUint64T  = 44;
+static SaFloatT  v_SaFloatT   = 55.555;
+static SaDoubleT v_SaDoubleT  = 666.6666;
+static char      str[]        = "777777";
+static SaStringT v_SaStringT  = str;
+
+#ifndef SA_EXTENDED_NAME_SOURCE
+static SaNameT v_SaNameT     = {11, "1234567890"};
+#else
+static char longDn[kOsafMaxDnLength] = {0};
+// @v_SaNameT will be initialized in @common_constructor
+static SaNameT v_SaNameT;
+#endif
+
+//>
+// Simulated IMM Model attributes
+// NOTE: Attribute name MUST follow the rule `cfg_attr_TYPE`
+//<
+
+// {SaImmAttrNameT, SaImmValueTypeT, SaImmAttrFlagsT, SaImmValueTypeT}
+static SaImmAttrDefinitionT_2 cfg_attr_SaInt32T = {
+  const_cast<char *>(AttrName(SaInt32T)),
+  SA_IMM_ATTR_SAINT32T,
+  SA_IMM_ATTR_CONFIG,
+  &AttrValue(SaInt32T)
+};
+
+static SaImmAttrDefinitionT_2 cfg_attr_SaUint32T = {
+  const_cast<char *>(AttrName(SaUint32T)),
+  SA_IMM_ATTR_SAUINT32T,
+  SA_IMM_ATTR_CONFIG,
+  &AttrValue(SaUint32T)
+};
+
+static SaImmAttrDefinitionT_2 cfg_attr_SaInt64T = {
+  const_cast<char *>(AttrName(SaInt64T)),
+  SA_IMM_ATTR_SAINT64T,
+  SA_IMM_ATTR_CONFIG,
+  &AttrValue(SaInt64T)
+};
+
+static SaImmAttrDefinitionT_2 cfg_attr_SaUint64T = {
+  const_cast<char *>(AttrName(SaUint64T)),
+  SA_IMM_ATTR_SAUINT64T,
+  SA_IMM_ATTR_CONFIG,
+  &AttrValue(SaUint64T)
+};
+
+static SaImmAttrDefinitionT_2 cfg_attr_SaFloatT = {
+  const_cast<char *>(AttrName(SaFloatT)),
+  SA_IMM_ATTR_SAFLOATT,
+  SA_IMM_ATTR_CONFIG,
+  &AttrValue(SaFloatT)
+};
+
+static SaImmAttrDefinitionT_2 cfg_attr_SaDoubleT = {
+  const_cast<char *>(AttrName(SaDoubleT)),
+  SA_IMM_ATTR_SADOUBLET,
+  SA_IMM_ATTR_CONFIG,
+  &AttrValue(SaDoubleT)
+};
+
+static SaImmAttrDefinitionT_2 cfg_attr_SaNameT = {
+  const_cast<char *>(AttrName(SaNameT)),
+  SA_IMM_ATTR_SANAMET,
+  SA_IMM_ATTR_CONFIG,
+  &AttrValue(SaNameT)
+};
+
+static SaImmAttrDefinitionT_2 cfg_attr_SaStringT = {
+  const_cast<char *>(AttrName(SaStringT)),
+  SA_IMM_ATTR_SASTRINGT,
+  SA_IMM_ATTR_CONFIG,
+  &AttrValue(SaStringT)
+};
+
+static SaImmAttrDefinitionT_2* cfg_attrs_t[] = {
+  &CfgAttrDefine(SaInt32T),
+  &CfgAttrDefine(SaUint32T),
+  &CfgAttrDefine(SaInt64T),
+  &CfgAttrDefine(SaUint64T),
+  &CfgAttrDefine(SaFloatT),
+  &CfgAttrDefine(SaDoubleT),
+  &CfgAttrDefine(SaNameT),
+  &CfgAttrDefine(SaStringT),
+  nullptr
+};
+
+// NOTE: No need to test Rt attribute objects as in term of GetResult usage,
+// it is based on Result data, and it has no different
+// b/w rt/cfg attribute.
+
+static const SaImmHandleT h = 1;
+static const char classname[] = "CfgClass";
+static immom::ImmOmClassDescriptionGet classobj(h, classname);
+
+// Setup data for ImmOmClassDescriptionGet
+static void SetupData() {
+  classobj.result_.class_category = SA_IMM_CLASS_CONFIG;
+  classobj.result_.attrs = cfg_attrs_t;
+}
+
+//==============================================================================
+// GetValue() interface
+//==============================================================================
+TEST(ImmOmClassDescriptionGet_GetValue, SingleSaInt32TValue_CfgObj) {
+  // Setup once
+  SetupData();
+  auto* out = classobj.GetValue<SaInt32T>(AttrName(SaInt32T));
+  ASSERT_EQ(*out, AttrValue(SaInt32T));
+}
+
+TEST(ImmOmClassDescriptionGet_GetValue, SingleSaUint32TValue_CfgObj) {
+  auto* out = classobj.GetValue<SaUint32T>(AttrName(SaUint32T));
+  ASSERT_EQ(*out, AttrValue(SaUint32T));
+}
+
+TEST(ImmOmClassDescriptionGet_GetValue, SingleSaInt64TValue_CfgObj) {
+  auto* out = classobj.GetValue<SaInt64T>(AttrName(SaInt64T));
+  ASSERT_EQ(*out, AttrValue(SaInt64T));
+}
+
+TEST(ImmOmClassDescriptionGet_GetValue, SingleSaUint64TValue_CfgObj) {
+  auto* out = classobj.GetValue<SaUint64T>(AttrName(SaUint64T));
+  ASSERT_EQ(*out, AttrValue(SaUint64T));
+}
+
+TEST(ImmOmClassDescriptionGet_GetValue, SingleSaFloatTValue_CfgObj) {
+  auto* out = classobj.GetValue<SaFloatT>(AttrName(SaFloatT));
+  ASSERT_EQ(*out, AttrValue(SaFloatT));
+}
+
+TEST(ImmOmClassDescriptionGet_GetValue, SingleSaDoubleTValue_CfgObj) {
+  auto* out = classobj.GetValue<SaDoubleT>(AttrName(SaDoubleT));
+  ASSERT_EQ(*out, AttrValue(SaDoubleT));
+}
+
+TEST(ImmOmClassDescriptionGet_GetValue, SingleSaNameTValue_CfgObj) {
+  SaNameT* out = classobj.GetValue<SaNameT>(AttrName(SaNameT));
+  std::string outstr{};
+
+  setenv("SA_ENABLE_EXTENDED_NAMES", "1", 1);
+
+  if (out != nullptr) {
+    outstr = osaf_extended_name_borrow(out);
+  }
+
+  SaNameT evalue = AttrValue(SaNameT);
+  std::string expstr = osaf_extended_name_borrow(&evalue);
+
+  ASSERT_EQ(outstr, expstr);
+}
+
+TEST(ImmOmClassDescriptionGet_GetValue, SingleSaStringTValue_CfgObj) {
+  auto* out = classobj.GetValue<SaStringT>(AttrName(SaStringT));
+  ASSERT_EQ(*out, AttrValue(SaStringT));
+}
+
+__attribute__((constructor)) static void omclassmanangement_constructor(void) {
+#ifdef SA_EXTENDED_NAME_SOURCE
+  memset(longDn, 'A', kOsafMaxDnLength);
+  osaf_extended_name_lend(longDn, &v_SaNameT);
+#endif
+}
diff --git a/src/immwrp/tests/omsearchnext_test.cc 
b/src/immwrp/tests/omsearchnext_test.cc
new file mode 100644
index 0000000..029aa7c
--- /dev/null
+++ b/src/immwrp/tests/omsearchnext_test.cc
@@ -0,0 +1,288 @@
+/*      -*- OpenSAF  -*-
+ *
+ * Copyright Ericsson AB 2017 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#include "gtest/gtest.h"
+
+#define protected public
+#define private public
+
+#include <stdlib.h>
+#include <string>
+#include <vector>
+#include "immwrp/immom/om_search_next.h"
+#include "immwrp/tests/common.h"
+#include "base/osaf_extended_name.h"
+
+//>
+// Prepare data for ImmOmSearchNext
+//<
+// Values of attributes that cover all data types
+// NOTE: variable names MUST follow the rule `v_TYPE`
+static SaInt32T  v_SaInt32T   = 11;
+static SaUint32T v_SaUint32T  = 22;
+static SaInt64T  v_SaInt64T   = 333;
+static SaUint64T v_SaUint64T  = 44;
+static SaFloatT  v_SaFloatT   = 55.555;
+static SaDoubleT v_SaDoubleT  = 666.6666;
+static char      str[]        = "777777";
+static SaStringT v_SaStringT  = str;
+
+#ifndef SA_EXTENDED_NAME_SOURCE
+static SaNameT v_SaNameT     = {11, "1234567890"};
+#else
+static char longDn[kOsafMaxDnLength] = {0};
+// @v_SaNameT will be initialized in @common_constructor
+static SaNameT v_SaNameT;
+#endif
+
+//>
+// Additional values for multiple-value attributes
+//<
+static SaInt32T  v_SaInt32T_1   = 111;
+static SaUint32T v_SaUint32T_1  = 222;
+static SaInt64T  v_SaInt64T_1   = 3333;
+static SaUint64T v_SaUint64T_1  = 444;
+static SaFloatT  v_SaFloatT_1   = 555.555;
+static SaDoubleT v_SaDoubleT_1  = 6666.6666;
+static char      str_1[]        = "7777777";
+static SaStringT v_SaStringT_1  = str_1;
+
+#ifndef SA_EXTENDED_NAME_SOURCE
+static SaNameT v_SaNameT_1     = {22, "12345678901234567890"};
+#else
+static char longDn_1[kOsafMaxDnLength] = {0};
+// @v_SaNameT will be initialized in @common_constructor
+static SaNameT v_SaNameT_1;
+#endif
+
+// {SaImmAttrNameT, SaImmValueTypeT, SaUint32T, SaImmAttrValueT*}
+static SaInt32T* m_SaInt32T[] = {
+  &AttrValue(SaInt32T),
+  &AttrValue1(SaInt32T),
+  nullptr
+};
+static SaImmAttrValuesT_2 m_cfg_attr_SaInt32T = {
+  const_cast<char *>(AttrName(SaInt32T)),
+  SA_IMM_ATTR_SAINT32T,
+  2,
+  reinterpret_cast<void**>(mValue(SaInt32T))
+};
+
+static SaUint32T* m_SaUint32T[] = {
+  &AttrValue(SaUint32T),
+  &AttrValue1(SaUint32T),
+  nullptr
+};
+static SaImmAttrValuesT_2 m_cfg_attr_SaUint32T = {
+  const_cast<char *>(AttrName(SaUint32T)),
+  SA_IMM_ATTR_SAUINT32T,
+  2,
+  reinterpret_cast<void**>(mValue(SaUint32T))
+};
+
+static SaInt64T* m_SaInt64T[] = {
+  &AttrValue(SaInt64T),
+  &AttrValue1(SaInt64T),
+  nullptr
+};
+static SaImmAttrValuesT_2 m_cfg_attr_SaInt64T = {
+  const_cast<char *>(AttrName(SaInt64T)),
+  SA_IMM_ATTR_SAINT64T,
+  2,
+  reinterpret_cast<void**>(mValue(SaInt64T))
+};
+
+static SaUint64T* m_SaUint64T[] = {
+  &AttrValue(SaUint64T),
+  &AttrValue1(SaUint64T),
+  nullptr
+};
+static SaImmAttrValuesT_2 m_cfg_attr_SaUint64T = {
+  const_cast<char *>(AttrName(SaUint64T)),
+  SA_IMM_ATTR_SAUINT64T,
+  2,
+  reinterpret_cast<void**>(mValue(SaUint64T))
+};
+
+static SaFloatT* m_SaFloatT[] = {
+  &AttrValue(SaFloatT),
+  &AttrValue1(SaFloatT),
+  nullptr
+};
+static SaImmAttrValuesT_2 m_cfg_attr_SaFloatT = {
+  const_cast<char *>(AttrName(SaFloatT)),
+  SA_IMM_ATTR_SAFLOATT,
+  2,
+  reinterpret_cast<void**>(mValue(SaFloatT))
+};
+
+static SaDoubleT* m_SaDoubleT[] = {
+  &AttrValue(SaDoubleT),
+  &AttrValue1(SaDoubleT),
+  nullptr
+};
+static SaImmAttrValuesT_2 m_cfg_attr_SaDoubleT = {
+  const_cast<char *>(AttrName(SaDoubleT)),
+  SA_IMM_ATTR_SADOUBLET,
+  2,
+  reinterpret_cast<void**>(mValue(SaDoubleT))
+};
+
+static SaNameT* m_SaNameT[] = {
+  &AttrValue(SaNameT),
+  &AttrValue1(SaNameT),
+  nullptr
+};
+static SaImmAttrValuesT_2 m_cfg_attr_SaNameT = {
+  const_cast<char *>(AttrName(SaNameT)),
+  SA_IMM_ATTR_SANAMET,
+  2,
+  reinterpret_cast<void**>(mValue(SaNameT))
+};
+
+static SaStringT* m_SaStringT[] = {
+  &AttrValue(SaStringT),
+  &AttrValue1(SaStringT),
+  nullptr
+};
+static SaImmAttrValuesT_2 m_cfg_attr_SaStringT = {
+  const_cast<char *>(AttrName(SaStringT)),
+  SA_IMM_ATTR_SASTRINGT,
+  2,
+  reinterpret_cast<void**>(mValue(SaStringT))
+};
+
+static SaImmAttrValuesT_2* m_cfg_attrs_t[] = {
+  &McfgAttrDefine(SaInt32T),
+  &McfgAttrDefine(SaUint32T),
+  &McfgAttrDefine(SaInt64T),
+  &McfgAttrDefine(SaUint64T),
+  &McfgAttrDefine(SaFloatT),
+  &McfgAttrDefine(SaDoubleT),
+  &McfgAttrDefine(SaNameT),
+  &McfgAttrDefine(SaStringT),
+  nullptr
+};
+
+static const SaImmHandleT h = 1;
+static const SaImmSearchHandleT sh = 2;
+static const char classname[] = "test=multipleTest";
+static immom::ImmOmSearchNext searchobj(h, sh);
+
+// Setup data for ImmOmClassDescriptionGet
+static void SetupData() {
+  searchobj.result_.dn = classname;
+  searchobj.result_.attrs = m_cfg_attrs_t;
+}
+
+//==============================================================================
+// GetMultiValue() interface
+//==============================================================================
+TEST(ImmOmSearchNext_GetMultiValue, MultipleSaInt32TValue_CfgObj) {
+  // Setup once
+  SetupData();
+  auto out = searchobj.GetMultiValue<SaInt32T>(AttrName(SaInt32T));
+  std::vector<SaInt32T> expected = {
+    AttrValue(SaInt32T),
+    AttrValue1(SaInt32T)
+  };
+  ASSERT_EQ(out, expected);
+}
+
+TEST(ImmOmSearchNext_GetMultiValue, MultipleSaUint32TValue_CfgObj) {
+  auto out = searchobj.GetMultiValue<SaUint32T>(AttrName(SaUint32T));
+  std::vector<SaUint32T> expected = {
+    AttrValue(SaUint32T),
+    AttrValue1(SaUint32T)
+  };
+  ASSERT_EQ(out, expected);
+}
+
+TEST(ImmOmSearchNext_GetMultiValue, MultipleSaInt64TValue_CfgObj) {
+  auto out = searchobj.GetMultiValue<SaInt64T>(AttrName(SaInt64T));
+  std::vector<SaInt64T> expected = {
+    AttrValue(SaInt64T),
+    AttrValue1(SaInt64T)
+  };
+  ASSERT_EQ(out, expected);
+}
+
+TEST(ImmOmSearchNext_GetMultiValue, MultipleSaUint64TValue_CfgObj) {
+  auto out = searchobj.GetMultiValue<SaUint64T>(AttrName(SaUint64T));
+  std::vector<SaUint64T> expected = {
+    AttrValue(SaUint64T),
+    AttrValue1(SaUint64T)
+  };
+  ASSERT_EQ(out, expected);
+}
+
+TEST(ImmOmSearchNext_GetMultiValue, MultipleSaFloatTValue_CfgObj) {
+  auto out = searchobj.GetMultiValue<SaFloatT>(AttrName(SaFloatT));
+  std::vector<SaFloatT> expected = {
+    AttrValue(SaFloatT),
+    AttrValue1(SaFloatT)
+  };
+  ASSERT_EQ(out, expected);
+}
+
+TEST(ImmOmSearchNext_GetMultiValue, MultipleSaDoubleTValue_CfgObj) {
+  auto out = searchobj.GetMultiValue<SaDoubleT>(AttrName(SaDoubleT));
+  std::vector<SaDoubleT> expected = {
+    AttrValue(SaDoubleT),
+    AttrValue1(SaDoubleT)
+  };
+  ASSERT_EQ(out, expected);
+}
+
+TEST(ImmOmSearchNext_GetMultiValue, MultipleSaNameTValue_CfgObj) {
+  auto out = searchobj.GetMultiValue<SaNameT>(AttrName(SaNameT));
+  std::string outstr{};
+  std::vector<std::string> vout{};
+
+  setenv("SA_ENABLE_EXTENDED_NAMES", "1", 1);
+  for (const auto v : out) {
+    outstr = osaf_extended_name_borrow(&v);
+    vout.push_back(outstr);
+  }
+
+  SaNameT evalue = AttrValue(SaNameT);
+  std::string expstr = osaf_extended_name_borrow(&evalue);
+  SaNameT evalue1 = AttrValue1(SaNameT);
+  std::string expstr1 = osaf_extended_name_borrow(&evalue1);
+  std::vector<std::string> expected = {expstr, expstr1};
+
+  ASSERT_EQ(vout, expected);
+}
+
+TEST(ImmOmSearchNext_GetMultiValue, MultipleSaStringTValue_CfgObj) {
+  auto out = searchobj.GetMultiValue<SaStringT>(AttrName(SaStringT));
+  std::vector<SaStringT> expected = {
+    AttrValue(SaStringT),
+    AttrValue1(SaStringT)
+  };
+  ASSERT_EQ(out, expected);
+}
+
+__attribute__((constructor)) static void omsearchnext_constructor(void) {
+#ifdef SA_EXTENDED_NAME_SOURCE
+  memset(longDn, 'A', kOsafMaxDnLength);
+  osaf_extended_name_lend(longDn, &v_SaNameT);
+
+  memset(longDn_1, 'B', kOsafMaxDnLength);
+  osaf_extended_name_lend(longDn_1, &v_SaNameT_1);
+#endif
+}
-- 
2.7.4


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to