tizen 2.4 release accepted/tizen/2.4/mobile/20151029.032842 submit/tizen_2.4/20151028.064257 tizen_2.4_mobile_release
authorjk7744.park <jk7744.park@samsung.com>
Sat, 24 Oct 2015 07:45:43 +0000 (16:45 +0900)
committerjk7744.park <jk7744.park@samsung.com>
Sat, 24 Oct 2015 07:45:43 +0000 (16:45 +0900)
24 files changed:
CMakeLists.txt [new file with mode: 0755]
LICENSE [new file with mode: 0755]
maps-plugin-here.changes [new file with mode: 0644]
maps-plugin-here.manifest [new file with mode: 0755]
maps-plugin-here.pc.in [new file with mode: 0755]
packaging/maps-plugin-here.spec [new file with mode: 0755]
src/here/here_api.cpp [new file with mode: 0755]
src/here/here_api.h [new file with mode: 0755]
src/here/here_base.cpp [new file with mode: 0644]
src/here/here_base.h [new file with mode: 0644]
src/here/here_geocode.cpp [new file with mode: 0755]
src/here/here_geocode.h [new file with mode: 0755]
src/here/here_manager.cpp [new file with mode: 0755]
src/here/here_manager.h [new file with mode: 0755]
src/here/here_place.cpp [new file with mode: 0755]
src/here/here_place.h [new file with mode: 0755]
src/here/here_revgeocode.cpp [new file with mode: 0755]
src/here/here_revgeocode.h [new file with mode: 0755]
src/here/here_route.cpp [new file with mode: 0755]
src/here/here_route.h [new file with mode: 0755]
src/here/here_types.h [new file with mode: 0755]
src/here/here_utils.cpp [new file with mode: 0755]
src/here/here_utils.h [new file with mode: 0755]
src/here_plugin.cpp [new file with mode: 0755]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..c065a38
--- /dev/null
@@ -0,0 +1,75 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+SET(pkg_name "maps-plugin-here")
+PROJECT(${pkg_name} C CXX)
+
+SET(CMAKE_INSTALL_PREFIX /usr)
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+
+# Dependencies
+SET(dependents "glib-2.0 gmodule-2.0 dlog capi-network-connection capi-appfw-app-manager capi-maps-service heremaps-engine")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED ${dependents})
+FOREACH(flag ${pkgs_CFLAGS})
+    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+    SET(EXTRA_CXXFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+
+# Build
+SET(CMAKE_INSTALL_PREFIX /usr)
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fvisibility=hidden -fPIC -Wall -Werror")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -Wall -fPIC -std=c++0x -fvisibility=hidden")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DEXPORT_API=__attribute__((visibility(\"default\")))")
+ADD_DEFINITIONS("-DTIZEN_DEBUG")
+
+
+# Main Include file
+SET(INC_DIR
+       src/here
+)
+
+INCLUDE_DIRECTORIES(
+       ${INC_DIR}
+)
+
+#This file must be corrected
+
+# Source Lists
+SET(SRCS
+       # Maps API
+       src/here_plugin.cpp
+
+       # Here plug-in
+       src/here/here_api.cpp
+       src/here/here_base.cpp
+       src/here/here_manager.cpp
+       src/here/here_geocode.cpp
+       src/here/here_place.cpp
+       src/here/here_revgeocode.cpp
+       src/here/here_route.cpp
+       src/here/here_utils.cpp
+)
+
+ADD_LIBRARY(${pkg_name} SHARED ${SRCS})
+
+SET_TARGET_PROPERTIES(${pkg_name}
+       PROPERTIES
+    VERSION ${FULLVER}
+    SOVERSION ${MAJORVER}
+    CLEAN_DIRECT_OUTPUT 1
+)
+
+TARGET_LINK_LIBRARIES(${pkg_name} ${pkgs_LDFLAGS})
+
+# Install
+INSTALL(TARGETS ${pkg_name} DESTINATION ${LIBDIR}/maps/plugins)
+
+# Test Suite
+#IF("${BINTYPE}" STREQUAL "eng")
+#ENDIF("${BINTYPE}" STREQUAL "eng")
diff --git a/LICENSE b/LICENSE
new file mode 100755 (executable)
index 0000000..e73c055
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,204 @@
+Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
diff --git a/maps-plugin-here.changes b/maps-plugin-here.changes
new file mode 100644 (file)
index 0000000..f7213bc
--- /dev/null
@@ -0,0 +1,24 @@
+[Version]   maps-plugin-here_0.1.4
+[Date]      24 Sep 2015
+[Title]     Fixed to use reference count of handler
+[Developer] Seechan Kim <cbible.kim@samsung.com>
+
+[Version]   maps-plugin-here_0.1.3
+[Date]      21 Sep 2015
+[Title]     Get here_key from metadata of application manifest
+[Developer] Young-Ae Kang <youngae.kang@samsung.com>
+
+[Version]   maps-plugin-here_0.1.2
+[Date]      18 Oct 2015
+[Title]     Fixed route query bugs
+[Developer] Seechan Kim <cbible.kim@samsung.com>
+
+[Version]   maps-plugin-here_0.1.1
+[Date]      09 Jun 2015
+[Title]     Fixed memory leaks
+[Developer] Seechan Kim <cbible.kim@samsung.com>
+
+[Version]   maps-plugin-here_0.1.0
+[Date]      01 July 2015
+[Title]     Initialize version
+[Developer] Seechan Kim <cbible.kim@samsung.com>
diff --git a/maps-plugin-here.manifest b/maps-plugin-here.manifest
new file mode 100755 (executable)
index 0000000..97e8c31
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+       <request>
+               <domain name="_"/>
+       </request>
+</manifest>
diff --git a/maps-plugin-here.pc.in b/maps-plugin-here.pc.in
new file mode 100755 (executable)
index 0000000..599cd78
--- /dev/null
@@ -0,0 +1,14 @@
+#Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=/usr
+libdir=/usr/lib
+includedir=@PC_INCLUDE@
+
+Name: @PC_NAME@
+Description: @PC_DESCRIPTION@
+Version: @VERSION@
+Requires: @PC_REQUIRED@
+Libs: -L${libdir} @PC_LDFLAGS@
+Cflags: -I${includedir}
+
diff --git a/packaging/maps-plugin-here.spec b/packaging/maps-plugin-here.spec
new file mode 100755 (executable)
index 0000000..45e07fe
--- /dev/null
@@ -0,0 +1,55 @@
+Name:       maps-plugin-here
+Summary:    Tizen HERE Maps Plug-in Library
+Version:    0.1.4
+Release:    1
+Group:      Location/Libraries
+License:    Apache-2.0
+Source0:    %{name}-%{version}.tar.gz
+
+BuildRequires: cmake
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(gmodule-2.0)
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(capi-maps-service)
+BuildRequires: capi-maps-service-plugin-devel
+BuildRequires: pkgconfig(heremaps-engine)
+BuildRequires: pkgconfig(capi-network-connection)
+BuildRequires: pkgconfig(capi-appfw-app-manager)
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+
+%description
+This packages provides Plugin APIs capsulating HERE Maps Engine Library for Maps Service Library.
+
+%prep
+%setup -q
+
+%build
+%if 0%{?tizen_build_binary_release_type_eng}
+export CFLAGS="$CFLAGS -DTIZEN_ENGINEER_MODE -g"
+export CXXFLAGS="$CXXFLAGS -DTIZEN_ENGINEER_MODE -g"
+export FFLAGS="$FFLAGS -DTIZEN_ENGINEER_MODE"
+%endif
+
+MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
+cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DMAJORVER=${MAJORVER} -DFULLVER=%{version} -DLIBDIR=%{_libdir}
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+mkdir -p %{buildroot}/usr/share/license
+cp LICENSE %{buildroot}/usr/share/license/%{name}
+
+%post
+/sbin/ldconfig
+
+%postun
+/sbin/ldconfig
+
+%files
+%manifest maps-plugin-here.manifest
+%defattr(-,root,root,-)
+%{_libdir}/maps/plugins/libmaps-plugin-here.so*
+/usr/share/license/maps-plugin-here
diff --git a/src/here/here_api.cpp b/src/here/here_api.cpp
new file mode 100755 (executable)
index 0000000..94de668
--- /dev/null
@@ -0,0 +1,541 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "here_api.h"
+#include "here_types.h"
+#include "here_geocode.h"
+#include "here_revgeocode.h"
+#include "here_place.h"
+#include "here_route.h"
+#include <common/HereConfig.h>
+
+
+using namespace HERE_PLUGIN_NAMESPACE_PREFIX;
+
+int HerePluginInit(maps_plugin_h *hPlugin)
+{
+       if (!hPlugin)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       HereManager::Create();
+
+       if (!HereManager::GetHandler())
+               return HERE_ERROR_INVALID_OPERATION;
+
+       HereManager::GetHandler()->SetProxyAddress();
+
+       return HERE_ERROR_NONE;
+}
+
+int HerePluginShutdown(maps_plugin_h hPlugin)
+{
+       if (!hPlugin)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       if (HereManager::GetHandler())
+       {
+               HereManager::GetHandler()->TerminateAllServices();
+               HereManager::GetHandler()->Close();
+       }
+
+       return HERE_ERROR_NONE;
+}
+
+int HerePluginSetProviderKey(const char* szKey)
+{
+       if (!szKey)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       if (!HereManager::GetHandler())
+               return HERE_ERROR_INVALID_OPERATION;
+
+       here_error_e error = HereManager::GetHandler()->SetCredentials(szKey);
+
+       return error;
+}
+
+int HerePluginGetProviderKey(char** szKey)
+{
+       if (!szKey)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       if (!HereManager::GetHandler())
+               return HERE_ERROR_INVALID_OPERATION;
+
+       here_error_e error = HereManager::GetHandler()->GetCredentials(szKey);
+
+       return error;
+}
+
+int HerePluginSetPreference(maps_preference_h hPref)
+{
+       if (!hPref)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       if (!HereManager::GetHandler())
+               return HERE_ERROR_INVALID_OPERATION;
+
+       here_error_e error = HereManager::GetHandler()->SetPreference(hPref);
+
+       return error;
+}
+
+int HerePluginGetPreference(maps_preference_h *hPref)
+{
+       if (!hPref)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       if (!HereManager::GetHandler())
+               return HERE_ERROR_INVALID_OPERATION;
+
+       here_error_e error = HereManager::GetHandler()->GetPreference(hPref);
+
+       return error;
+}
+
+int HerePluginGeocode(const char* szAddr,
+       maps_item_hashtable_h hPref, maps_service_geocode_cb pCbFunc,
+       void *pUserData, int *nReqId)
+{
+       /* checking parmaters */
+       if (!szAddr || (szAddr && *szAddr == '\0') || !pCbFunc || !nReqId)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       if (!HereManager::GetHandler())
+               return HERE_ERROR_INVALID_OPERATION;
+
+       /* creating instance */
+       HereGeocode *pGeocode =
+               (HereGeocode*)(HereManager::GetHandler()->CreateInstance(HereManager::HERE_SVC_GEOCODE,
+               (void*)pCbFunc, pUserData, nReqId));
+
+       if(!pGeocode)
+               return HERE_ERROR_SERVICE_NOT_AVAILABLE;
+
+       /* sending request */
+       here_error_e error = HERE_ERROR_NONE;
+
+       do {
+               error = pGeocode->PrepareQuery();
+               if (error != HERE_ERROR_NONE) break;
+
+               error = pGeocode->PreparePreference(hPref);
+
+               error = pGeocode->StartGeocode(szAddr);
+       } while(0);
+
+       /* finishing task */
+       if(error != HERE_ERROR_NONE)
+               pGeocode->TerminateService();
+
+       return error;
+}
+
+int HerePluginGeocodeByStructuredAddress(const maps_address_h hAddr,
+       maps_item_hashtable_h hPref, maps_service_geocode_cb pCbFunc,
+       void *pUserData, int *nReqId)
+{
+       /* checking parmaters */
+       if (!hAddr || !pCbFunc || !nReqId)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       if (!HereManager::GetHandler())
+               return HERE_ERROR_INVALID_OPERATION;
+
+       /* creating instance */
+       HereGeocode *pGeocode =
+               (HereGeocode*)(HereManager::GetHandler()->CreateInstance(HereManager::HERE_SVC_GEOCODE,
+               (void*)pCbFunc, pUserData, nReqId));
+
+       if(!pGeocode)
+               return HERE_ERROR_SERVICE_NOT_AVAILABLE;
+
+       /* sending request */
+       here_error_e error = HERE_ERROR_NONE;
+
+       do {
+               error = pGeocode->PrepareQuery();
+               if (error != HERE_ERROR_NONE) break;
+
+               error = pGeocode->PreparePreference(hPref);
+
+               error = pGeocode->StartGeocodeByStructuredAddress(hAddr);
+       } while(0);
+
+       /* finishing task */
+       if(error != HERE_ERROR_NONE)
+               pGeocode->TerminateService();
+
+       return error;
+}
+
+int HerePluginGeocodeInsideArea(const char* szAddr, maps_area_h hArea,
+       maps_item_hashtable_h hPref, maps_service_geocode_cb pCbFunc,
+       void *pUserData, int *nReqId)
+{
+       /* checking parmaters */
+       if (!szAddr || (szAddr && *szAddr == '\0') || !pCbFunc || !nReqId)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       if (!hArea || !HereUtils::IsValid(*(maps_area_s*)hArea))
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       if (!HereManager::GetHandler())
+               return HERE_ERROR_INVALID_OPERATION;
+
+       /* creating instance */
+       HereGeocode *pGeocode =
+               (HereGeocode*)(HereManager::GetHandler()->CreateInstance(HereManager::HERE_SVC_GEOCODE,
+               (void*)pCbFunc, pUserData, nReqId));
+
+       if(!pGeocode)
+               return HERE_ERROR_SERVICE_NOT_AVAILABLE;
+
+       /* sending request */
+       here_error_e error = HERE_ERROR_NONE;
+
+       do {
+               error = pGeocode->PrepareQuery();
+               if (error != HERE_ERROR_NONE) break;
+
+               error = pGeocode->PreparePreference(hPref);
+
+               error = pGeocode->StartGeocodeInsideArea(szAddr, hArea);
+       } while(0);
+
+       /* finishing task */
+       if(error != HERE_ERROR_NONE)
+               pGeocode->TerminateService();
+
+       return error;
+}
+
+int HerePluginReverseGeocode(double dLatitude, double dLongitude,
+       maps_item_hashtable_h hPref, maps_service_reverse_geocode_cb pCbFunc,
+       void *pUserData, int *nReqId)
+{
+       /* checking parmaters */
+       if (!HereUtils::IsValidCoord(dLatitude, dLongitude))
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       if (!pCbFunc || !nReqId)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       if (!HereManager::GetHandler())
+               return HERE_ERROR_INVALID_OPERATION;
+
+       /* creating instance */
+       HereRevGeocode *pRevGeocode =
+               (HereRevGeocode*)(HereManager::GetHandler()->CreateInstance(HereManager::HERE_SVC_REV_GEOCODE,
+               (void*)pCbFunc, pUserData, nReqId));
+
+       if(!pRevGeocode)
+               return HERE_ERROR_SERVICE_NOT_AVAILABLE;
+
+       /* sending request */
+       here_error_e error = HERE_ERROR_UNKNOWN;
+
+       do {
+               error = pRevGeocode->PrepareQuery();
+               if (error != HERE_ERROR_NONE) break;
+
+               error = pRevGeocode->PreparePreference(hPref);
+
+               error = pRevGeocode->PreparePosition(dLatitude, dLongitude);
+               if (error != HERE_ERROR_NONE) break;
+
+               error = pRevGeocode->StartRevGeocode(hPref);
+       } while(0);
+
+       /* finishing task */
+       if(error != HERE_ERROR_NONE)
+               pRevGeocode->TerminateService();
+
+       return error;
+}
+
+int HerePluginSearchPlace(maps_coordinates_h hPos, int nDistance,
+       maps_item_hashtable_h hPref, maps_place_filter_h hFilter, maps_service_search_place_cb pCbFunc,
+       void *pUserData, int *nReqId)
+{
+       /* checking parmaters */
+       if (!hPos || !HereUtils::IsValid(*(maps_coordinates_s*)hPos) || nDistance <= 0)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       if (!hFilter || !pCbFunc || !nReqId)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       if (!HereManager::GetHandler())
+               return HERE_ERROR_INVALID_OPERATION;
+
+       /* creating instance */
+       HerePlace *pPlace =
+               (HerePlace*)(HereManager::GetHandler()->CreateInstance(HereManager::HERE_SVC_PLACE,
+               (void*)pCbFunc, pUserData, nReqId));
+
+       if(!pPlace)
+               return HERE_ERROR_SERVICE_NOT_AVAILABLE;
+
+       /* sending request */
+       here_error_e error = HERE_ERROR_NONE;
+
+       do {
+               error = pPlace->PrepareDiscoveryQuery();
+               if (error != HERE_ERROR_NONE) break;
+
+               error = pPlace->PrepareDiscoveryPreference(hPref);
+
+               error = pPlace->PrepareDiscoveryFilter(hFilter);
+               if (error != HERE_ERROR_NONE) break;
+
+               error = pPlace->StartDiscoveryPlace(hPos, nDistance);
+       } while(0);
+
+       /* finishing task */
+       if(error != HERE_ERROR_NONE)
+               pPlace->TerminateService();
+
+       return error;
+}
+
+int HerePluginSearchPlaceByArea(maps_area_h hArea,
+       maps_item_hashtable_h hPref, maps_place_filter_h hFilter, maps_service_search_place_cb pCbFunc,
+       void *pUserData, int *nReqId)
+{
+       /* checking parmaters */
+       if (!hArea || !HereUtils::IsValid(*(maps_area_s*)hArea))
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       if (!hFilter || !pCbFunc || !nReqId)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       if (!HereManager::GetHandler())
+               return HERE_ERROR_INVALID_OPERATION;
+
+       /* creating instance */
+       HerePlace *pPlace =
+               (HerePlace*)(HereManager::GetHandler()->CreateInstance(HereManager::HERE_SVC_PLACE,
+               (void*)pCbFunc, pUserData, nReqId));
+
+       if(!pPlace)
+               return HERE_ERROR_SERVICE_NOT_AVAILABLE;
+
+       /* sending request */
+       here_error_e error = HERE_ERROR_NONE;
+
+       do {
+               error = pPlace->PrepareDiscoveryQuery();
+               if (error != HERE_ERROR_NONE) break;
+
+               error = pPlace->PrepareDiscoveryPreference(hPref);
+
+               error = pPlace->PrepareDiscoveryFilter(hFilter);
+               if (error != HERE_ERROR_NONE) break;
+
+               error = pPlace->StartDiscoveryPlaceByArea(hArea);
+       } while(0);
+
+       /* finishing task */
+       if(error != HERE_ERROR_NONE)
+               pPlace->TerminateService();
+
+       return error;
+}
+
+int HerePluginSearchPlaceByAddress(const char* szAddr, maps_area_h hArea,
+       maps_item_hashtable_h hPref, maps_place_filter_h hFilter, maps_service_search_place_cb pCbFunc,
+       void * pUserData, int *nReqId)
+{
+       /* checking parmaters */
+       if (!szAddr || (szAddr && *szAddr == '\0') || !hFilter || !pCbFunc || !nReqId)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       if (!hArea || !HereUtils::IsValid(*(maps_area_s*)hArea))
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       if (!HereManager::GetHandler())
+               return HERE_ERROR_INVALID_OPERATION;
+
+       /* creating instance */
+       HerePlace *pPlace =
+               (HerePlace*)(HereManager::GetHandler()->CreateInstance(HereManager::HERE_SVC_PLACE,
+               (void*)pCbFunc, pUserData, nReqId));
+
+       if(!pPlace)
+               return HERE_ERROR_SERVICE_NOT_AVAILABLE;
+
+       /* sending request */
+       here_error_e error = HERE_ERROR_NONE;
+
+       do {
+               error = pPlace->PrepareDiscoveryQuery();
+               if (error != HERE_ERROR_NONE) break;
+
+               error = pPlace->PrepareDiscoveryPreference(hPref);
+
+               error = pPlace->PrepareDiscoveryFilter(hFilter);
+               if (error != HERE_ERROR_NONE) break;
+
+               error = pPlace->StartDiscoveryPlaceByAddress(szAddr, hArea);
+       } while(0);
+
+       /* finishing task */
+       if(error != HERE_ERROR_NONE)
+               pPlace->TerminateService();
+
+       return error;
+}
+
+int HerePluginSearchPlaceDetails(const char* szUrl,
+       maps_item_hashtable_h hPref, maps_service_search_place_cb pCbFunc,
+       void *pUserData, int *nReqId)
+{
+       /* checking parmaters */
+       if (!szUrl || (szUrl && *szUrl == '\0') || !pCbFunc || !nReqId)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       if (!HereManager::GetHandler())
+               return HERE_ERROR_INVALID_OPERATION;
+
+       /* creating instance */
+       HerePlace *pPlace =
+               (HerePlace*)(HereManager::GetHandler()->CreateInstance(HereManager::HERE_SVC_PLACE,
+               (void*)pCbFunc, pUserData, nReqId));
+
+       if(!pPlace)
+               return HERE_ERROR_SERVICE_NOT_AVAILABLE;
+
+       /* sending request */
+       here_error_e error = HERE_ERROR_NONE;
+
+       do {
+               error = pPlace->PreparePlaceDetailsQuery();
+               if (error != HERE_ERROR_NONE) break;
+
+               error = pPlace->PreparePlaceDetailsPreference(hPref);
+
+               error = pPlace->StartPlaceDetails(szUrl);
+       } while(0);
+
+       /* finishing task */
+       if(error != HERE_ERROR_NONE)
+               pPlace->TerminateService();
+
+       return error;
+}
+
+int HerePluginSearchRoute(maps_coordinates_h hOrigin, maps_coordinates_h hDestination,
+       maps_item_hashtable_h hPref, maps_service_search_route_cb pCbFunc,
+       void *pUserData, int *nReqId)
+{
+       /* checking parmaters */
+       if (!hOrigin || !hDestination || !pCbFunc || !nReqId)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       if (!HereUtils::IsValid(*(maps_coordinates_s*)hOrigin) ||
+               !HereUtils::IsValid(*(maps_coordinates_s*)hDestination))
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       if (!HereManager::GetHandler())
+               return HERE_ERROR_INVALID_OPERATION;
+
+       /* creating instance */
+       HereRoute *pRoute =
+               (HereRoute*)(HereManager::GetHandler()->CreateInstance(HereManager::HERE_SVC_ROUTE,
+               (void*)pCbFunc, pUserData, nReqId));
+
+       if(!pRoute)
+               return HERE_ERROR_SERVICE_NOT_AVAILABLE;
+
+       /* sending request */
+       here_error_e error = HERE_ERROR_NONE;
+
+       do {
+               error = pRoute->PrepareQuery();
+               if (error != HERE_ERROR_NONE) break;
+
+               error = pRoute->PreparePreference(hPref);
+
+               error = pRoute->PrepareWaypoint(hOrigin, hDestination);
+               if (error != HERE_ERROR_NONE) break;
+
+               error = pRoute->StartRoute();
+       } while(0);
+
+       /* finishing task */
+       if(error != HERE_ERROR_NONE)
+               pRoute->TerminateService();
+
+       return error;
+}
+
+int HerePluginSearchRouteWaypoints(const maps_coordinates_h* hWaypointList, int nWaypointNum,
+       maps_item_hashtable_h hPref, maps_service_search_route_cb pCbFunc,
+       void* pUserData, int *nReqId)
+{
+       /* checking parmaters */
+       if (!hWaypointList || nWaypointNum < 2 || !pCbFunc || !nReqId)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       for (int i=0; i<nWaypointNum; i++)
+       {
+               if (!HereUtils::IsValid(*(maps_coordinates_s*)hWaypointList[i]))
+                       return HERE_ERROR_INVALID_PARAMETER;
+       }
+
+       if (!HereManager::GetHandler())
+               return HERE_ERROR_INVALID_OPERATION;
+
+       /* creating instance */
+       HereRoute *pRoute =
+               (HereRoute*)(HereManager::GetHandler()->CreateInstance(HereManager::HERE_SVC_ROUTE,
+               (void*)pCbFunc, pUserData, nReqId));
+
+       if(!pRoute)
+               return HERE_ERROR_SERVICE_NOT_AVAILABLE;
+
+       /* sending request */
+       here_error_e error = HERE_ERROR_NONE;
+
+       do {
+               error = pRoute->PrepareQuery();
+               if (error != HERE_ERROR_NONE) break;
+
+               error = pRoute->PrepareWaypoint(hWaypointList, nWaypointNum);
+               if (error != HERE_ERROR_NONE) break;
+
+               error = pRoute->PreparePreference(hPref);
+
+               error = pRoute->StartRoute();
+       } while(0);
+
+       /* finishing task */
+       if(error != HERE_ERROR_NONE)
+               pRoute->TerminateService();
+
+       return error;
+}
+
+int HerePluginCancelRequest(int nReqId)
+{
+       if (nReqId <= 0)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       if (!HereManager::GetHandler())
+               return HERE_ERROR_INVALID_OPERATION;
+
+       return (HereManager::GetHandler()->CancelInstance(nReqId));
+}
diff --git a/src/here/here_api.h b/src/here/here_api.h
new file mode 100755 (executable)
index 0000000..61694ef
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef _LOCATION_HERE_API_H_
+#define _LOCATION_HERE_API_H_
+
+#include <maps_plugin.h>
+
+int HerePluginInit(maps_plugin_h *hPlugin);
+
+int HerePluginShutdown(maps_plugin_h hPlugin);
+
+int HerePluginSetProviderKey(const char* szKey);
+
+int HerePluginGetProviderKey(char** szKey);
+
+int HerePluginSetPreference(maps_preference_h hPref);
+
+int HerePluginGetPreference(maps_preference_h *hPref);
+
+int HerePluginGeocode(const char* szAddr,
+       maps_item_hashtable_h hPref, maps_service_geocode_cb pCbFunc,
+       void *pUserData, int *nReqId);
+
+int HerePluginGeocodeByStructuredAddress(const maps_address_h hAddr,
+       maps_item_hashtable_h hPref, maps_service_geocode_cb pCbFunc,
+       void *pUserData, int *nReqId);
+
+int HerePluginGeocodeInsideArea(const char* szAddr, maps_area_h hArea,
+       maps_item_hashtable_h hPref, maps_service_geocode_cb pCbFunc,
+       void *pUserData, int *nReqId);
+
+int HerePluginReverseGeocode(double dLatitude, double dLongitude,
+       maps_item_hashtable_h hPref, maps_service_reverse_geocode_cb pCbFunc,
+       void *pUserData, int *nReqId);
+
+int HerePluginSearchPlace(maps_coordinates_h hPos, int nDistance,
+       maps_item_hashtable_h hPref, maps_place_filter_h hFilter, maps_service_search_place_cb pCbFunc,
+       void * pUserData, int *nReqId);
+
+int HerePluginSearchPlaceByArea(maps_area_h hArea,
+       maps_item_hashtable_h hPref, maps_place_filter_h hFilter, maps_service_search_place_cb pCbFunc,
+       void * pUserData, int *nReqId);
+
+int HerePluginSearchPlaceByAddress(const char* szAddr, maps_area_h hArea,
+       maps_item_hashtable_h hPref, maps_place_filter_h hFilter, maps_service_search_place_cb pCbFunc,
+       void * pUserData, int *nReqId);
+
+int HerePluginSearchPlaceDetails(const char* szUrl,
+       maps_item_hashtable_h hPref, maps_service_search_place_cb pCbFunc,
+       void * pUserData, int *nReqId);
+
+int HerePluginSearchRoute(maps_coordinates_h hOrigin, maps_coordinates_h hDestination,
+       maps_item_hashtable_h hPref, maps_service_search_route_cb pCbFunc,
+       void *pUserData, int *nReqId);
+
+int HerePluginSearchRouteWaypoints(const maps_coordinates_h* hWaypointList, int nWaypointNum,
+       maps_item_hashtable_h hPref, maps_service_search_route_cb pCbFunc,
+       void* pUserData, int *nReqId);
+
+int HerePluginCancelRequest(int nReqId);
+
+#endif //_LOCATION_HERE_API_H_
\ No newline at end of file
diff --git a/src/here/here_base.cpp b/src/here/here_base.cpp
new file mode 100644 (file)
index 0000000..bd8a87e
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "here_base.h"
+#include "here_manager.h"
+
+
+HERE_PLUGIN_BEGIN_NAMESPACE
+
+HereBase::HereBase()
+{
+       m_nRestReqId = 0;
+       m_bCanceled = 0;
+       m_nReqId = 0;
+}
+
+HereBase::~HereBase()
+{
+       if (HereManager::GetHandler())
+               HereManager::GetHandler()->CloseInstance(m_nReqId);
+}
+
+void HereBase::TerminateService(void)
+{
+       if(m_nRestReqId)
+       {
+               m_bCanceled = 1;
+               return;
+       }
+       delete this;
+}
+
+gint HereBase::GetReqId(void)
+{
+       return m_nReqId;
+}
+
+gint HereBase::GetRestReqId(void)
+{
+       return m_nRestReqId;
+}
+
+HERE_PLUGIN_END_NAMESPACE
diff --git a/src/here/here_base.h b/src/here/here_base.h
new file mode 100644 (file)
index 0000000..8d085e0
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LOCATION_HERE_BASE_H_
+#define _LOCATION_HERE_BASE_H_
+
+//plug-in header
+#include "here_utils.h"
+
+HERE_PLUGIN_BEGIN_NAMESPACE
+
+class HereBase
+{
+public:
+       /**
+        *This is the default constructor for Geocoder.
+        */
+
+       HereBase();
+
+       /**
+        *This is the default destructor for Geocoder.
+        */
+
+       virtual ~HereBase();
+
+       void TerminateService(void);
+
+       gint GetReqId(void);
+       gint GetRestReqId(void);
+
+protected:
+       gint m_nReqId;
+       gint m_nRestReqId;
+       void* m_pCbFunc;
+       void* m_pUserData;
+       gboolean m_bCanceled;
+};
+
+HERE_PLUGIN_END_NAMESPACE
+
+#endif //_LOCATION_HERE_BASE_H_
+
diff --git a/src/here/here_geocode.cpp b/src/here/here_geocode.cpp
new file mode 100755 (executable)
index 0000000..b00ef61
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "here_geocode.h"
+
+HERE_PLUGIN_BEGIN_NAMESPACE
+
+HereGeocode::HereGeocode(void *pCbFunc, void *pUserData, int nReqId)
+{
+       m_pQuery = NULL;
+
+       m_pCbFunc = pCbFunc;
+       m_pUserData = pUserData;
+       m_nReqId = nReqId;
+}
+
+HereGeocode::~HereGeocode()
+{
+       if (m_pQuery)
+       {
+               delete m_pQuery;
+               m_pQuery = NULL;
+       }
+}
+
+here_error_e HereGeocode::PrepareQuery()
+{
+       if (m_pQuery)
+               return HERE_ERROR_PERMISSION_DENIED;
+
+       m_pQuery = new GeoCoderQuery();
+
+       if (!m_pQuery)
+               return HERE_ERROR_OUT_OF_MEMORY;
+       else
+               return HERE_ERROR_NONE;
+}
+
+here_error_e HereGeocode::PreparePreference(maps_preference_h hPref)
+{
+       if (!m_pQuery)
+               return HERE_ERROR_OUT_OF_MEMORY;
+
+       if (!hPref)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       int ret;
+       char *szLanguage = NULL;
+       ret = maps_preference_get_language(hPref, &szLanguage);
+       if (ret == MAPS_ERROR_NONE && szLanguage && *szLanguage)
+       {
+               m_pQuery->AppendPreferredLanguage(szLanguage);
+               g_free(szLanguage);
+       }
+
+       int nMaxResults;
+       ret = maps_preference_get_max_results(hPref, &nMaxResults);
+       if (ret == MAPS_ERROR_NONE)
+       {
+               m_pQuery->SetMaxResults((size_t)nMaxResults);
+       }
+
+       return HERE_ERROR_NONE;
+}
+
+here_error_e HereGeocode::StartGeocode(const char* szAddr)
+{
+       if (!m_pQuery)
+               return HERE_ERROR_OUT_OF_MEMORY;
+
+       if (!szAddr || (szAddr && strlen(szAddr) <= 0))
+               return HERE_ERROR_INVALID_PARAMETER;
+
+
+       String sSearch(szAddr);
+       m_pQuery->SetSearchtext(sSearch);
+
+
+       m_nRestReqId = m_pQuery->Execute(*this, NULL);
+
+       return (m_nRestReqId > 0 ? HERE_ERROR_NONE : HERE_ERROR_INVALID_OPERATION);
+}
+
+here_error_e HereGeocode::StartGeocodeInsideArea(const char* szAddr, const maps_area_h hArea)
+{
+       if (!m_pQuery)
+               return HERE_ERROR_OUT_OF_MEMORY;
+
+       if (!szAddr || (szAddr && strlen(szAddr) <= 0) || !hArea)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+
+       String sSearch(szAddr);
+       m_pQuery->SetSearchtext(sSearch);
+
+       maps_area_s *pArea = (maps_area_s *)hArea;
+       if (pArea->type == MAPS_AREA_RECTANGLE)
+       {
+               double dLatTL = pArea->rect.top_left.latitude;
+               double dLngTL = pArea->rect.top_left.longitude;
+               GeoCoordinates geoCoordTL(dLatTL, dLngTL);
+
+               double dLatBR = pArea->rect.bottom_right.latitude;
+               double dLngBR = pArea->rect.bottom_right.longitude;
+               GeoCoordinates geoCoordBR(dLatBR, dLngBR);
+
+               GeoBoundingBox BoundingBox(geoCoordTL, geoCoordBR);
+
+               m_pQuery->SetBoundingBox(BoundingBox);
+       }
+       else if (pArea->type == MAPS_AREA_CIRCLE)
+       {
+               MAPS_LOGD("HERE Maps is not supported circle type in GeocoderQuery");
+               return HERE_ERROR_NOT_SUPPORTED;
+       }
+       else {
+               return HERE_ERROR_INVALID_PARAMETER;
+       }
+
+
+       m_nRestReqId = m_pQuery->Execute(*this, NULL);
+
+       return (m_nRestReqId > 0 ? HERE_ERROR_NONE : HERE_ERROR_INVALID_OPERATION);
+}
+
+here_error_e HereGeocode::StartGeocodeByStructuredAddress(const maps_address_h hAddr)
+{
+       if (!m_pQuery)
+               return HERE_ERROR_OUT_OF_MEMORY;
+
+       if (!hAddr)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+
+       Address rAddress;
+
+       int ret;
+       char *szCountry = NULL;
+       ret = maps_address_get_country(hAddr, &szCountry);
+       if (ret == MAPS_ERROR_NONE && szCountry && *szCountry)
+               rAddress.SetCountry(String(szCountry));
+       g_free(szCountry);
+
+       char *szCountryCode = NULL;
+       ret = maps_address_get_country_code(hAddr, &szCountryCode);
+       if (ret == MAPS_ERROR_NONE && szCountryCode && *szCountryCode)
+               rAddress.SetCountryCode(String(szCountryCode));
+       g_free(szCountryCode);
+
+       char *szCounty = NULL;
+       ret = maps_address_get_county(hAddr, &szCounty);
+       if (ret == MAPS_ERROR_NONE && szCounty && *szCounty)
+               rAddress.SetCounty(String(szCounty));
+       g_free(szCounty);
+
+       char *szState = NULL;
+       ret = maps_address_get_state(hAddr, &szState);
+       if (ret == MAPS_ERROR_NONE && szState && *szState)
+               rAddress.SetState(String(szState));
+       g_free(szState);
+
+       char *szCity = NULL;
+       ret = maps_address_get_city(hAddr, &szCity);
+       if (ret == MAPS_ERROR_NONE && szCity && *szCity)
+               rAddress.SetCity(String(szCity));
+       g_free(szCity);
+
+       char *szDistrict = NULL;
+       ret = maps_address_get_district(hAddr, &szDistrict);
+       if (ret == MAPS_ERROR_NONE && szDistrict && *szDistrict)
+               rAddress.SetDistrict(String(szDistrict));
+       g_free(szDistrict);
+
+       char *szStreet = NULL;
+       ret = maps_address_get_street(hAddr, &szStreet);
+       if (ret == MAPS_ERROR_NONE && szStreet && *szStreet)
+               rAddress.SetStreet(String(szStreet));
+       g_free(szStreet);
+
+       char *szBuildingNumber = NULL;
+       ret = maps_address_get_building_number(hAddr, &szBuildingNumber);
+       if (ret == MAPS_ERROR_NONE && szBuildingNumber && *szBuildingNumber)
+               rAddress.SetHouseNumber(String(szBuildingNumber));
+       g_free(szBuildingNumber);
+
+       char *szPostalCode = NULL;
+       ret = maps_address_get_postal_code(hAddr, &szPostalCode);
+       if (ret == MAPS_ERROR_NONE && szPostalCode && *szPostalCode)
+               rAddress.SetPostalCode(String(szPostalCode));
+       g_free(szPostalCode);
+
+       //not defined in maps-service
+       //rAddress.SetLabel(String(sLabel));
+       //rAddress.SetFloor(String(sFloor));
+       //rAddress.SetSuite(String(sSuite));
+
+       m_pQuery->SetAddress(rAddress);
+
+
+
+       m_nRestReqId = m_pQuery->Execute(*this, NULL);
+
+       return (m_nRestReqId > 0 ? HERE_ERROR_NONE : HERE_ERROR_INVALID_OPERATION);
+}
+
+void HereGeocode::OnGeoCoderReply(const GeoCoderReply& Reply)
+{
+       if (m_bCanceled) // ignore call back if it was cancelled.
+       {
+               delete this;
+               return;
+       }
+
+       Result* pResult;
+       size_t nResults = Reply.GetNumResults();
+       GeoCoordinates hereCoord;
+       maps_coordinates_h mapsCoord;
+
+       if (nResults == 0)
+       {
+               ((maps_service_geocode_cb)m_pCbFunc)(MAPS_ERROR_NOT_FOUND, m_nReqId,
+                       0, 1, NULL, m_pUserData);
+               delete this;
+               return;
+       }
+
+       for (size_t i = 0 ; i < nResults; i++)
+       {
+               pResult = (Result*)Reply.GetResult(i);
+
+               if (pResult)
+               {
+                       hereCoord = (pResult->GetLocation()).GetDisplayPosition();
+               }
+               else
+               {
+                       hereCoord.SetLatitude(0.0);
+                       hereCoord.SetLongitude(0.0);
+               }
+
+               maps_error_e error = (maps_error_e)maps_coordinates_create(
+                                    hereCoord.GetLatitude(), hereCoord.GetLongitude(), &mapsCoord);
+
+               if (m_bCanceled)
+               {
+                       if (mapsCoord) maps_coordinates_destroy(mapsCoord);
+                       break;
+               }
+               else
+               {
+                       if (((maps_service_geocode_cb)m_pCbFunc)(error, m_nReqId, i,
+                               nResults, mapsCoord, m_pUserData) == FALSE)
+                       {
+                               delete this;
+                               return;
+                       }
+               }
+       }
+
+       delete this;
+}
+
+HERE_PLUGIN_END_NAMESPACE
+
diff --git a/src/here/here_geocode.h b/src/here/here_geocode.h
new file mode 100755 (executable)
index 0000000..4f37176
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LOCATION_HERE_GEOCODER_H_
+#define _LOCATION_HERE_GEOCODER_H_
+
+//plug-in header
+#include "here_manager.h"
+
+// maps-service header
+#include <maps_address.h>
+#include <maps_coordinates.h>
+#include <maps_area.h>
+
+//map engine header
+#include <geocoder/GeoCoderQuery.h>
+#include <geocoder/GeoCoderQueryListener.h>
+#include <geocoder/GeoCoderReply.h>
+#include <geocoder/Result.h>
+#include <common/GeoLocation.h>
+#include <common/Address.h>
+
+
+HERE_PLUGIN_BEGIN_NAMESPACE
+
+using namespace HERE_MAPS_NAMESPACE_PREFIX;
+
+class HereGeocode
+: public HereBase
+, public GeoCoderQueryListener
+{
+public:
+       /**
+        *This is the default constructor for Geocoder.
+        */
+
+       HereGeocode(void *pCbFunc, void *pUserData, int nReqId);
+
+       /**
+        *This is the default destructor for Geocoder.
+        */
+
+       ~HereGeocode();
+
+       here_error_e PrepareQuery();
+       here_error_e PreparePreference(maps_preference_h hPref);
+
+       here_error_e StartGeocode(const char* szAddr);
+       here_error_e StartGeocodeInsideArea(const char* szAddr, const maps_area_h hArea);
+       here_error_e StartGeocodeByStructuredAddress(const maps_address_h hAddr);
+
+       virtual void OnGeoCoderReply(const GeoCoderReply& Reply);
+
+private:
+       GeoCoderQuery* m_pQuery;
+};
+
+HERE_PLUGIN_END_NAMESPACE
+
+#endif //_LOCATION_HERE_GEOCODER_H_
diff --git a/src/here/here_manager.cpp b/src/here/here_manager.cpp
new file mode 100755 (executable)
index 0000000..31dcb1e
--- /dev/null
@@ -0,0 +1,461 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "here_manager.h"
+#include "here_base.h"
+#include "here_geocode.h"
+#include "here_revgeocode.h"
+#include "here_place.h"
+#include "here_route.h"
+#include "here_utils.h"
+#include <common/HereConfig.h>
+
+using namespace HERE_PLUGIN_NAMESPACE_PREFIX;
+
+HERE_PLUGIN_BEGIN_NAMESPACE
+
+HereManager *HereManager::m_pHereManager = NULL;
+int HereManager::m_nRefCnt = 0;
+pthread_mutex_t g_mtxRef;
+
+HereManager::HereManager()
+: m_nNextReqId(1),
+  m_hPref(NULL)
+{
+       m_hConnection = NULL;
+       pthread_mutex_init(&g_mtxRef, NULL);
+}
+
+HereManager::~HereManager()
+{
+       if (m_hConnection)
+       {
+               connection_unset_type_changed_cb(m_hConnection);
+               connection_destroy(m_hConnection);
+               m_hConnection = NULL;
+       }
+       pthread_mutex_destroy(&g_mtxRef);
+}
+
+bool HereManager::Create()
+{
+       bool result = false;
+
+       if (!m_pHereManager)
+       {
+               m_pHereManager = new HereManager();
+       }
+
+       pthread_mutex_lock(&g_mtxRef);
+       if (m_pHereManager)
+       {
+               m_nRefCnt++;
+               result = true;
+               MAPS_LOGD("Created a HereManager instance (%d).", m_nRefCnt);
+       }
+       pthread_mutex_unlock(&g_mtxRef);
+
+       m_pHereManager->SetCredentials();
+       return result;
+}
+
+void HereManager::Close()
+{
+       pthread_mutex_lock(&g_mtxRef);
+       if (--m_nRefCnt == 0 && m_pHereManager)
+       {
+               delete m_pHereManager;
+               m_pHereManager = NULL;
+       }
+       MAPS_LOGD("Closed a HereManager instance (%d).", m_nRefCnt);
+       pthread_mutex_unlock(&g_mtxRef);
+}
+
+HereManager* HereManager::GetHandler()
+{
+       return m_pHereManager;
+}
+
+void* HereManager::CreateInstance(HereSvcType nHereSvc, void* pCbFunc,
+       void* pUserData, int *nReqId)
+{
+       HereBase *pHere = NULL;
+
+       *nReqId = m_nNextReqId++;
+
+       switch(nHereSvc)
+       {
+       case HERE_SVC_GEOCODE:
+               pHere = (HereBase*)new HereGeocode(pCbFunc, pUserData, *nReqId);
+               break;
+
+       case HERE_SVC_REV_GEOCODE:
+               pHere = (HereBase*)new HereRevGeocode(pCbFunc, pUserData, *nReqId);
+               break;
+
+       case HERE_SVC_PLACE:
+               pHere = (HereBase*)new HerePlace(pCbFunc, pUserData, *nReqId);
+               break;
+
+       case HERE_SVC_ROUTE:
+               pHere = (HereBase*)new HereRoute(pCbFunc, pUserData, *nReqId);
+               break;
+
+       default:
+               return NULL;
+       }
+
+       m_HereList.push_back(pHere);
+       return pHere;
+}
+
+here_error_e HereManager::CloseInstance(int nReqId)
+{
+       HereSvcList::iterator it;
+
+       for (it = m_HereList.begin(); it != m_HereList.end(); it++)
+       {
+               if ((*it)->GetReqId() == nReqId)
+               {
+                       m_HereList.erase(it);
+                       break;
+               }
+       }
+       return HERE_ERROR_NONE;
+}
+
+here_error_e HereManager::CancelInstance(int nReqId)
+{
+       HereSvcList::iterator it;
+
+       for (it = m_HereList.begin(); it != m_HereList.end(); it++)
+       {
+               if ((*it)->GetReqId() == nReqId)
+               {
+                       m_HereList.erase(it);
+                       RestItemHandle::Cancel((*it)->GetRestReqId());
+                       (*it)->TerminateService();
+                       return HERE_ERROR_NONE;
+               }
+       }
+       return HERE_ERROR_NOT_FOUND;
+}
+
+bool HereManager::AppInfoMetadataCb(const char *metadata_key, const char *metadata_value, void *user_data)
+{
+       if (!metadata_key || !metadata_value)
+               return false;
+
+       if (!strncmp(metadata_key, "http://tizen.org/metadata/here_key", 35) && strlen(metadata_value) > 0 )
+       {
+               if (m_pHereManager->SetCredentials(metadata_value) == HERE_ERROR_NONE)
+               {
+                       MAPS_LOGD("Succeeded getting credential from metadata");
+               }
+
+               return false;
+       }
+
+       return true;
+}
+
+here_error_e HereManager::SetCredentials(void)
+{
+       int nRet = 0;
+       app_info_h hAppInfo;
+       pid_t nProcessId = -1;
+       char *strAppId = NULL;
+
+       nProcessId = getpid();
+       nRet = app_manager_get_app_id(nProcessId, &strAppId);
+       if (nRet != APP_MANAGER_ERROR_NONE)
+       {
+               MAPS_LOGI("Get app_id [%ld]. nRet[%d]", nProcessId, nRet);
+               return HERE_ERROR_NONE;
+       }
+
+       nRet = app_info_create(strAppId, &hAppInfo);
+       if (nRet != APP_MANAGER_ERROR_NONE)
+       {
+               MAPS_LOGI("Get appinfo of [%s]. nRet[%d]", strAppId, nRet);
+               if (strAppId) free(strAppId);
+               return HERE_ERROR_NONE;
+       }
+
+       if (strAppId) free(strAppId);
+
+       nRet = app_info_foreach_metadata(hAppInfo, AppInfoMetadataCb, NULL);
+       if (nRet != APP_MANAGER_ERROR_NONE)
+       {
+               MAPS_LOGI("Get metadata. nRet[%d]", nRet);
+       }
+
+       nRet = app_info_destroy(hAppInfo);
+       if (nRet != APP_MANAGER_ERROR_NONE)
+       {
+               MAPS_LOGI("Destroy app_info. nRet[%d]", nRet);
+       }
+
+       return HERE_ERROR_NONE;
+}
+
+here_error_e HereManager::SetCredentials(const char *szKey)
+{
+       if (!szKey)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       String strKey(szKey);
+       String strAppId, strAppCode;
+       size_t nCodeStart;
+
+       nCodeStart = strKey.find("/");
+
+       if(nCodeStart == 0 || nCodeStart >= (strKey.length()-1))
+       {
+               MAPS_LOGE("[error] Key type fault : Key type should be as like XXXXX/YYYYY");
+               return HERE_ERROR_INVALID_PARAMETER;
+       }
+
+       strAppId = strKey.substr(0, nCodeStart);
+       strAppCode = strKey.substr(nCodeStart+1, std::string::npos);
+
+       if(!ApplicationContext::GetInstance().Initialize(strAppCode, strAppId))
+               return HERE_ERROR_INVALID_OPERATION;
+
+       //MAPS_LOGD("[success] credential setted to 'XXXXX/XXXXX'");
+
+       return HERE_ERROR_NONE;
+}
+
+here_error_e HereManager::GetCredentials(char **szKey)
+{
+       if (!szKey)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       if (!ApplicationContext::GetInstance().IsInitialized())
+               return HERE_ERROR_NOT_FOUND;
+
+       String strCredentials = ApplicationContext::GetInstance().GetAppId() + "/" +
+                               ApplicationContext::GetInstance().GetAppCode();
+
+       *szKey = g_strndup(strCredentials.c_str(), strCredentials.length());
+
+       if (*szKey == NULL)
+               return HERE_ERROR_INVALID_OPERATION;
+
+       //MAPS_LOGD("current credential : %s", *szKey);
+
+       return HERE_ERROR_NONE;
+}
+
+here_error_e HereManager::SetPreference(maps_preference_h hPref)
+{
+       int error = HERE_ERROR_NONE;
+
+       if (!hPref)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       if (m_hPref)
+       {
+               if (maps_preference_destroy(m_hPref) != MAPS_ERROR_NONE)
+                       return HERE_ERROR_INVALID_OPERATION;
+       }
+
+       do {
+               error = maps_preference_clone(hPref, &m_hPref);
+               if (error != MAPS_ERROR_NONE) break;
+
+               char *szLanguage = NULL;
+               error = maps_preference_get_language(hPref, &szLanguage);
+               if (error == MAPS_ERROR_NONE && szLanguage && strlen(szLanguage) > 0)
+                       ApplicationContext::GetInstance().SetPreferredLanguage(String(szLanguage));
+       } while(0);
+
+       return (here_error_e)ConvertToHereError(error);
+}
+
+here_error_e HereManager::GetPreference(maps_preference_h *hPref)
+{
+       int ret = HERE_ERROR_NONE;
+
+       if (!hPref)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       if (!m_hPref)
+               return HERE_ERROR_NOT_FOUND;
+
+       ret = maps_preference_clone(m_hPref, hPref);
+
+       return (here_error_e)ConvertToHereError(ret);
+}
+
+maps_preference_h HereManager::GetPreference()
+{
+       return m_hPref;
+}
+
+void HereManager::TerminateAllServices(void)
+{
+       if (m_nRefCnt > 0) return;
+
+
+       HereSvcList::iterator it;
+
+       while (1)
+       {
+               if (m_HereList.empty())
+               {
+                       break;
+               }
+               it = m_HereList.begin();
+
+               try {
+                       m_HereList.erase(it);
+                       (*it)->TerminateService();
+               }
+               catch (std::exception &e) {
+               }
+       };
+
+       if (m_hPref)
+       {
+               maps_preference_destroy(m_hPref);
+               m_hPref = NULL;
+       }
+}
+
+here_error_e HereManager::ConvertNetworkErrorCode(const int nErrorCode)
+{
+       here_error_e err = HERE_ERROR_NONE;
+
+       switch (nErrorCode)
+       {
+       case CONNECTION_ERROR_NONE:
+               //MAPS_LOGD("No error");
+               err = HERE_ERROR_NONE;
+               break;
+       case CONNECTION_ERROR_INVALID_PARAMETER:
+               MAPS_LOGD("Invalid parameter");
+               err = HERE_ERROR_INVALID_PARAMETER;
+               break;
+       case CONNECTION_ERROR_OUT_OF_MEMORY:
+               MAPS_LOGD("Out of memory error");
+               err = HERE_ERROR_OUT_OF_MEMORY;
+               break;
+       case CONNECTION_ERROR_INVALID_OPERATION:
+               MAPS_LOGD("Invalid Operation");
+               err = HERE_ERROR_INVALID_OPERATION;
+               break;
+       case CONNECTION_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED:
+               MAPS_LOGD("Address family not supported");
+               err = HERE_ERROR_NOT_SUPPORTED;
+               break;
+       case CONNECTION_ERROR_PERMISSION_DENIED:
+               MAPS_LOGD("Permission denied");
+               err = HERE_ERROR_PERMISSION_DENIED;
+               break;
+       case CONNECTION_ERROR_OPERATION_FAILED:
+               MAPS_LOGD("Operation failed");
+               err = HERE_ERROR_INVALID_OPERATION;
+               break;
+       case CONNECTION_ERROR_ITERATOR_END:
+               MAPS_LOGD("End of iteration");
+               break;
+       case CONNECTION_ERROR_NO_CONNECTION:
+               MAPS_LOGD("There is no connection");
+               err = HERE_ERROR_NETWORK_UNREACHABLE;
+               break;
+       case CONNECTION_ERROR_NOW_IN_PROGRESS:
+               MAPS_LOGD("Now in progress");
+               err = HERE_ERROR_RESOURCE_BUSY;
+               break;
+       case CONNECTION_ERROR_ALREADY_EXISTS:
+               MAPS_LOGD("Already exists");
+               break;
+       case CONNECTION_ERROR_OPERATION_ABORTED:
+               MAPS_LOGD("Operation is aborted");
+               err = HERE_ERROR_CANCELED;
+               break;
+       case CONNECTION_ERROR_DHCP_FAILED:
+               MAPS_LOGD("DHCP failed");
+               break;
+       case CONNECTION_ERROR_INVALID_KEY:
+               MAPS_LOGD("Invalid key");
+               err = HERE_ERROR_KEY_NOT_AVAILABLE;
+               break;
+       case CONNECTION_ERROR_NO_REPLY:
+               MAPS_LOGD("No Reply");
+               err = HERE_ERROR_RESOURCE_BUSY;
+               break;
+       case CONNECTION_ERROR_NOT_SUPPORTED:
+               MAPS_LOGD("Not Supported");
+               err = HERE_ERROR_NOT_SUPPORTED;
+               break;
+       default:
+               MAPS_LOGD("Unknown");
+               break;
+       }
+       //MAPS_LOGD("nErrorCode = 0x%08X", nErrorCode);
+
+       return err;
+}
+
+here_error_e HereManager::SetProxyAddress()
+{
+       int errorCode = CONNECTION_ERROR_NONE;
+
+       char *proxy_address = NULL;
+
+       if (!m_hConnection)
+       {
+               errorCode = connection_create(&m_hConnection);
+               if (errorCode == CONNECTION_ERROR_NONE)
+               {
+                       errorCode = connection_set_type_changed_cb(m_hConnection, NetworkStateChangedIndCb, this);
+
+               }
+       }
+       if (errorCode != CONNECTION_ERROR_NONE)
+               return ConvertNetworkErrorCode(errorCode);
+
+       errorCode = connection_get_proxy(m_hConnection, CONNECTION_ADDRESS_FAMILY_IPV4, &proxy_address);
+       if (errorCode == CONNECTION_ERROR_NONE)
+       {
+               MAPS_LOGD("Proxy = %s", (proxy_address ? proxy_address : "(null)"));
+               Tizen::Maps::HereConfig::SetProxyAddress(proxy_address);
+       }
+       g_free(proxy_address);
+
+       return ConvertNetworkErrorCode(errorCode);
+}
+
+void HereManager::NetworkStateChangedIndCb(connection_type_e type, void *user_data)
+{
+       MAPS_LOGD("Network state is changed. type=%d", type);
+
+       if (!user_data) return;
+
+       HereManager *pManager = (HereManager*)user_data;
+
+       if ((type != CONNECTION_TYPE_DISCONNECTED) && (type != CONNECTION_TYPE_BT))
+               pManager->SetProxyAddress();
+}
+
+HERE_PLUGIN_END_NAMESPACE
+
diff --git a/src/here/here_manager.h b/src/here/here_manager.h
new file mode 100755 (executable)
index 0000000..f68a5ea
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LOCATION_HERE_MANAGER_H_
+#define _LOCATION_HERE_MANAGER_H_
+
+//common header
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#include <math.h>
+#include <vector>
+
+//platform header
+#include <net_connection.h>
+#include <app_manager.h>
+
+//plug-in header
+#include "here_base.h"
+#include "here_api.h"
+#include "here_types.h"
+#include "here_utils.h"
+
+//map engine header
+#include <common/ApplicationContext.h>
+#include <common/HereConfig.h>
+
+HERE_PLUGIN_BEGIN_NAMESPACE
+
+class HereManager;
+
+typedef std::vector<HereBase*> HereSvcList;
+
+class HereManager
+{
+public:
+       /**
+        *This is the default constructor for Geocoder.
+        */
+
+       HereManager();
+
+       /**
+        *This is the default destructor for Geocoder.
+        */
+
+       virtual ~HereManager();
+
+       enum HereSvcType {
+               HERE_SVC_GEOCODE,
+               HERE_SVC_REV_GEOCODE,
+               HERE_SVC_PLACE,
+               HERE_SVC_ROUTE
+       };
+
+       void* CreateInstance(HereSvcType nHereSvc, void* pCbFunc, void* pUserData, int *nReqId);
+       here_error_e CloseInstance(int nReqId);
+       here_error_e CancelInstance(int nReqId);
+       here_error_e SetCredentials(const char* provider_key);
+       here_error_e GetCredentials(char** provider_key);
+       void TerminateAllServices(void);
+
+       here_error_e SetProxyAddress();
+       here_error_e SetPreference(maps_preference_h hPref);
+       here_error_e GetPreference(maps_preference_h *hPref);
+       maps_preference_h GetPreference();
+
+       static bool Create();
+       static HereManager* GetHandler();
+       static void Close();
+
+private:
+       here_error_e SetCredentials();
+       static bool AppInfoMetadataCb(const char *metadata_key, const char *metadata_value, void *user_data);
+       static void NetworkStateChangedIndCb(connection_type_e type, void *user_data);
+       static here_error_e ConvertNetworkErrorCode(const int nErrorCode);
+       connection_h m_hConnection;
+       static int m_nRefCnt;
+       static HereManager *m_pHereManager;
+
+protected:
+       HereSvcList m_HereList;
+       gint m_nNextReqId;
+       maps_preference_h m_hPref;
+};
+
+HERE_PLUGIN_END_NAMESPACE
+
+#endif //_LOCATION_HERE_MANAGER_H_
diff --git a/src/here/here_place.cpp b/src/here/here_place.cpp
new file mode 100755 (executable)
index 0000000..53432c7
--- /dev/null
@@ -0,0 +1,1299 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "here_place.h"
+
+HERE_PLUGIN_BEGIN_NAMESPACE
+
+HerePlace::HerePlace(void *pCbFunc, void *pUserData, int nReqId)
+{
+       m_pDiscoveryQuery = NULL;
+       m_pPlaceDetailsQuery = NULL;
+
+       m_pCbFunc = pCbFunc;
+       m_pUserData = pUserData;
+       m_nReqId = nReqId;
+
+       m_nReplyCnt = 0;
+       m_nReplyIdx = 0;
+       m_szSortBy = NULL;
+}
+
+HerePlace::~HerePlace()
+{
+       if (m_pDiscoveryQuery)
+       {
+               delete m_pDiscoveryQuery;
+               m_pDiscoveryQuery = NULL;
+       }
+
+       if (m_pPlaceDetailsQuery)
+       {
+               delete m_pPlaceDetailsQuery;
+               m_pPlaceDetailsQuery = NULL;
+       }
+
+       while(!m_PlaceList.empty())
+       {
+               maps_place_destroy(m_PlaceList.front());
+               m_PlaceList.pop_front();
+       }
+}
+
+here_error_e HerePlace::PrepareDiscoveryQuery()
+{
+       if (m_pDiscoveryQuery)
+               return HERE_ERROR_PERMISSION_DENIED;
+
+        m_pDiscoveryQuery = new DiscoveryQuery();
+
+       if (!m_pDiscoveryQuery)
+               return HERE_ERROR_OUT_OF_MEMORY;
+       else
+               return HERE_ERROR_NONE;
+}
+
+here_error_e HerePlace::PrepareDiscoveryPreference(maps_preference_h hPref)
+{
+       if (!m_pDiscoveryQuery)
+               return HERE_ERROR_OUT_OF_MEMORY;
+
+       if (!hPref)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+
+       int ret;
+       char *szLanguage = NULL;
+       ret = maps_preference_get_language(hPref, &szLanguage);
+       if (ret == MAPS_ERROR_NONE && szLanguage && *szLanguage)
+               m_pDiscoveryQuery->SetLanguage(szLanguage);
+       g_free(szLanguage);
+
+       int nMaxResults;
+       ret = maps_preference_get_max_results(hPref, &nMaxResults);
+       if (ret == MAPS_ERROR_NONE)
+               m_pDiscoveryQuery->SetMaxResults((size_t)nMaxResults);
+
+       char *szSortBy;
+       ret = maps_preference_get(hPref, MAPS_PLACE_FILTER_SORT_BY, &szSortBy);
+       if (ret == MAPS_ERROR_NONE)
+               m_szSortBy = szSortBy;
+
+       return HERE_ERROR_NONE;
+}
+
+here_error_e HerePlace::PrepareDiscoveryFilter(maps_place_filter_h hFilter)
+{
+       if (!m_pDiscoveryQuery)
+               return HERE_ERROR_OUT_OF_MEMORY;
+
+       if (!hFilter)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       int ret;
+       maps_place_category_h mapsCate = NULL;
+       if (maps_place_filter_get_category(hFilter, &mapsCate) == MAPS_ERROR_NONE)
+       {
+               CategoryList hereCateList;
+               Category hereCate;
+               char *szId = NULL, *szName = NULL, *szUrl = NULL;
+
+               ret = maps_place_category_get_name(mapsCate, &szName);
+               if (ret == MAPS_ERROR_NONE && szName && *szName)
+                       hereCate.SetTitle(szName);
+               g_free(szName);
+
+               ret = maps_place_category_get_url(mapsCate, &szUrl);
+               if (ret == MAPS_ERROR_NONE && szUrl && *szUrl)
+                       hereCate.SetHref(szUrl);
+               g_free(szUrl);
+
+               ret = maps_place_category_get_id(mapsCate, &szId);
+               if (ret == MAPS_ERROR_NONE && szId && *szId)
+               {
+                       hereCate.SetCategoryId(CategoryId(szId));
+                       hereCateList.push_back(hereCate);
+                       m_pDiscoveryQuery->SetCategoriesFilter(hereCateList);
+               }
+               g_free(szId);
+
+               maps_place_category_destroy(mapsCate);
+       }
+
+       char *szName = NULL;
+       ret = maps_place_filter_get_place_name(hFilter, &szName);
+       if (ret == MAPS_ERROR_NONE && szName && *szName)
+               m_pDiscoveryQuery->SetSearchText(szName);
+       g_free(szName);
+
+       return HERE_ERROR_NONE;
+}
+
+here_error_e HerePlace::StartDiscoveryPlace(maps_coordinates_h hCoord, int nDistance)
+{
+       if (!m_pDiscoveryQuery)
+               return HERE_ERROR_OUT_OF_MEMORY;
+
+       if (!hCoord)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+
+       if (m_pDiscoveryQuery->GetSearchText().empty())
+       {
+               m_pDiscoveryQuery->SetType(DiscoveryQuery::QT_EXPLORE);
+
+               double dLat, dLon;
+               maps_coordinates_get_latitude(hCoord, &dLat);
+               maps_coordinates_get_longitude(hCoord, &dLon);
+               GeoCoordinates geoCoord(dLat, dLon);
+
+               if (nDistance > 0)
+               {
+                       GeoBoundingCircle geoCircle(geoCoord, nDistance);
+                       m_pDiscoveryQuery->SetArea(geoCircle);
+               }
+               else if (nDistance == 0)
+               {
+                       m_pDiscoveryQuery->SetProximity(geoCoord);
+               }
+               else
+                       return HERE_ERROR_INVALID_PARAMETER;
+
+               m_nRestReqId = m_pDiscoveryQuery->Execute(*this, NULL);
+
+               return (m_nRestReqId > 0 ? HERE_ERROR_NONE : HERE_ERROR_INVALID_OPERATION);
+       }
+       else
+       {
+               here_error_e error;
+               maps_area_h hArea = NULL;
+               maps_area_create_circle(hCoord, nDistance, &hArea);
+               error = StartDiscoveryPlaceByAddress(m_pDiscoveryQuery->GetSearchText().data(), hArea);
+               maps_area_destroy(hArea);
+               return error;
+       }
+}
+
+here_error_e HerePlace::StartDiscoveryPlaceByArea(maps_area_h hArea)
+{
+       if (!m_pDiscoveryQuery)
+               return HERE_ERROR_OUT_OF_MEMORY;
+
+       if (!hArea)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+
+       if (m_pDiscoveryQuery->GetSearchText().empty())
+       {
+               m_pDiscoveryQuery->SetType(DiscoveryQuery::QT_EXPLORE);
+
+               maps_area_s *pArea = (maps_area_s*)hArea;
+               if (pArea->type == MAPS_AREA_RECTANGLE)
+               {
+                       GeoBoundingBox box(pArea->rect.top_left.longitude, pArea->rect.bottom_right.longitude,
+                                          pArea->rect.bottom_right.latitude, pArea->rect.top_left.latitude);
+                       m_pDiscoveryQuery->SetArea(box);
+               }
+               else if (pArea->type == MAPS_AREA_CIRCLE)
+               {
+                       GeoCoordinates coord(pArea->circle.center.latitude, pArea->circle.center.longitude);
+                       GeoBoundingCircle circle(coord, pArea->circle.radius);
+                       m_pDiscoveryQuery->SetArea(circle);
+               }
+               else
+                       return HERE_ERROR_INVALID_PARAMETER;
+
+
+               m_nRestReqId = m_pDiscoveryQuery->Execute(*this, NULL);
+
+               return (m_nRestReqId > 0 ? HERE_ERROR_NONE : HERE_ERROR_INVALID_OPERATION);
+       }
+       else
+       {
+               return StartDiscoveryPlaceByAddress(m_pDiscoveryQuery->GetSearchText().data(), hArea);
+       }
+}
+
+here_error_e HerePlace::StartDiscoveryPlaceByAddress(const char *szAddr, maps_area_h hArea)
+{
+       if (!m_pDiscoveryQuery)
+               return HERE_ERROR_OUT_OF_MEMORY;
+
+       if (!szAddr || (szAddr && strlen(szAddr) <= 0) || !hArea)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+
+       m_pDiscoveryQuery->SetType(DiscoveryQuery::QT_SEARCH);
+
+       String szSearchText = szAddr;
+       if (m_pDiscoveryQuery->GetSearchText().size())
+               szSearchText += " " + m_pDiscoveryQuery->GetSearchText();
+       m_pDiscoveryQuery->SetSearchText(szSearchText);
+
+       maps_area_s *pArea = (maps_area_s*)hArea;
+       if (pArea->type == MAPS_AREA_RECTANGLE)
+       {
+               double dLat1 = pArea->rect.top_left.latitude;
+               double dLng1 = pArea->rect.top_left.longitude;
+               double dLat2 = pArea->rect.bottom_right.latitude;
+               double dLng2 = pArea->rect.bottom_right.longitude;
+               double dLat = (dLat1 + dLat2) / 2;
+               double dLng = (dLng1 + dLng2) / 2;
+
+               GeoCoordinates geoCoord(dLat, dLng);
+               m_pDiscoveryQuery->SetProximity(geoCoord);
+       }
+       else if(pArea->type == MAPS_AREA_CIRCLE)
+       {
+               double dLat = pArea->circle.center.latitude;
+               double dLng = pArea->circle.center.longitude;
+               GeoCoordinates geoCoord(dLat, dLng);
+               m_pDiscoveryQuery->SetProximity(geoCoord);
+       }
+
+
+       m_nRestReqId = m_pDiscoveryQuery->Execute(*this, NULL);
+
+       return (m_nRestReqId > 0 ? HERE_ERROR_NONE : HERE_ERROR_INVALID_OPERATION);
+}
+
+here_error_e HerePlace::PreparePlaceDetailsQuery()
+{
+       if (m_pPlaceDetailsQuery)
+               return HERE_ERROR_PERMISSION_DENIED;
+
+       m_pPlaceDetailsQuery = new PlaceDetailsQuery();
+
+       if (!m_pPlaceDetailsQuery)
+               return HERE_ERROR_OUT_OF_MEMORY;
+       else
+               return HERE_ERROR_NONE;
+}
+
+here_error_e HerePlace::PreparePlaceDetailsPreference(maps_preference_h hPref)
+{
+       if (!m_pPlaceDetailsQuery)
+               return HERE_ERROR_OUT_OF_MEMORY;
+
+       if (!hPref)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       int ret;
+       char *szLanguage = NULL;
+       ret = maps_preference_get_language(hPref, &szLanguage);
+       if (ret == MAPS_ERROR_NONE && szLanguage && *szLanguage)
+               m_pPlaceDetailsQuery->SetLanguage(szLanguage);
+       g_free(szLanguage);
+
+       return HERE_ERROR_NONE;
+}
+
+here_error_e HerePlace::StartPlaceDetails(const char *szPlaceId)
+{
+       if (!m_pPlaceDetailsQuery)
+               return HERE_ERROR_OUT_OF_MEMORY;
+
+       if (!szPlaceId || (szPlaceId && strlen(szPlaceId) <= 0))
+               return HERE_ERROR_INVALID_PARAMETER;
+
+
+       m_pPlaceDetailsQuery->SetPlaceId(szPlaceId);
+
+
+       m_nRestReqId = m_pPlaceDetailsQuery->Execute(*this, NULL);
+
+       return (m_nRestReqId > 0 ? HERE_ERROR_NONE : HERE_ERROR_INVALID_OPERATION);
+}
+
+here_error_e HerePlace::StartPlaceDetailsInternal(const char *szUrl)
+{
+       if (!szUrl || (szUrl && strlen(szUrl) <= 0))
+               return HERE_ERROR_INVALID_PARAMETER;
+
+
+       std::unique_ptr<PlaceDetailsQuery> pPlaceDetailsQuery (new (std::nothrow)PlaceDetailsQuery());
+
+
+       bool bExcuted = (int)(pPlaceDetailsQuery->Execute(*this, NULL, szUrl) > 0);
+
+       return (bExcuted ? HERE_ERROR_NONE : HERE_ERROR_INVALID_OPERATION);
+}
+
+void HerePlace::OnDiscoverReply (const DiscoveryReply &Reply)
+{
+       if (m_bCanceled) /* ignore call back if it was cancelled. */
+       {
+               delete this;
+               return;
+       }
+
+       maps_place_h mapsPlace;
+       PlaceItemList herePlaceList = Reply.GetPlaceItems();
+       PlaceItemList::iterator herePlaceIt;
+       SearchItemList hereSearchList = Reply.GetSearchItems();
+       SearchItemList::iterator hereSearchIt;
+       LinkObject hereLinkObj;
+       GeoCoordinates hereCoord;
+       maps_coordinates_h mapsCoord;
+       Category hereCate;
+       maps_place_category_h mapsCate;
+       maps_place_rating_h mapsRating;
+       int error = MAPS_ERROR_UNKNOWN, sub_error;
+       bool is_valid, isPending;
+
+
+       m_nReplyIdx = 0;
+       m_nReplyCnt = herePlaceList.size() + hereSearchList.size();
+
+       if (m_nReplyCnt == 0)
+       {
+               ((maps_service_search_place_cb)m_pCbFunc)(MAPS_ERROR_NOT_FOUND, m_nReqId,
+                       0, 1, NULL, m_pUserData);
+               delete this;
+               return;
+       }
+
+       for (herePlaceIt = herePlaceList.begin();
+               herePlaceIt != herePlaceList.end() && !m_bCanceled;
+               herePlaceIt++)
+       {
+               isPending = false;
+
+               if ((error = maps_place_create(&mapsPlace)) == MAPS_ERROR_NONE)
+               {
+                       /* title, uri, id */
+                       hereLinkObj = herePlaceIt->GetLinkObject();
+
+                       if (!hereLinkObj.GetTitle().empty())
+                               maps_place_set_name(mapsPlace, (char*)hereLinkObj.GetTitle().c_str());
+
+                       if (!hereLinkObj.GetHref().empty())
+                               maps_place_set_uri(mapsPlace, (char*)hereLinkObj.GetHref().c_str());
+
+                       if (!hereLinkObj.GetId().empty())
+                               maps_place_set_id(mapsPlace, (char*)hereLinkObj.GetId().c_str());
+
+                       /* icon */
+                       /* type */
+
+                       /* position */
+                       hereCoord = herePlaceIt->GetPosition();
+                       if (maps_coordinates_create(hereCoord.GetLatitude(), hereCoord.GetLongitude(),
+                               &mapsCoord) == MAPS_ERROR_NONE)
+                       {
+                               maps_place_set_location(mapsPlace, mapsCoord);
+                               maps_coordinates_destroy(mapsCoord);
+                       }
+
+                       /* rating (optional) */
+                       if (maps_place_rating_create(&mapsRating) == MAPS_ERROR_NONE)
+                       {
+                               maps_place_rating_set_average(mapsRating, herePlaceIt->GetAverageRating());
+                               maps_place_set_rating(mapsPlace, mapsRating);
+                               maps_place_rating_destroy(mapsRating);
+                       }
+
+                       /* category (optional) */
+                       hereCate = herePlaceIt->GetCategory();
+
+                       maps_item_list_h mapsCateList;
+                       if (maps_item_list_create(&mapsCateList) == MAPS_ERROR_NONE)
+                       {
+                               if (maps_place_category_create(&mapsCate) == MAPS_ERROR_NONE)
+                               {
+                                       is_valid = false;
+
+                                       if (!hereCate.GetCategoryId().ToString().empty())
+                                       {
+                                               sub_error = maps_place_category_set_id(mapsCate,
+                                                               (char*)hereCate.GetCategoryId().ToString().c_str());
+                                               is_valid |= (sub_error == MAPS_ERROR_NONE);
+                                       }
+
+                                       if (!hereCate.GetTitle().empty())
+                                       {
+                                               sub_error = maps_place_category_set_name(mapsCate,
+                                                               (char*)hereCate.GetTitle().c_str());
+                                               is_valid |= (sub_error == MAPS_ERROR_NONE);
+                                       }
+
+                                       if (!hereCate.GetHref().empty())
+                                       {
+                                               sub_error = maps_place_category_set_url(mapsCate,
+                                                               (char*)hereCate.GetHref().c_str());
+                                               is_valid |= (sub_error == MAPS_ERROR_NONE);
+                                       }
+
+                                       if (is_valid)
+                                       {
+                                               maps_item_list_append(mapsCateList, mapsCate, maps_place_category_clone);
+                                               maps_place_set_categories(mapsPlace, mapsCateList);
+                                               maps_item_list_remove_all(mapsCateList, maps_place_category_destroy);
+                                       }
+                                       maps_place_category_destroy(mapsCate);
+                               }
+                               maps_item_list_destroy(mapsCateList);
+                       }
+
+                       /* distance */
+                       maps_place_set_distance(mapsPlace, (int)herePlaceIt->GetDistance());
+
+                       /* sponser */
+                       /* herePlaceList.GetIsSponsored() */
+
+                       /* vicinity */
+
+                       /* If needed PlaceDetails information, postpone to send a reply */
+                       if(__sending_place_details_query_automatically)
+                       {
+                               hereLinkObj = herePlaceIt->GetLinkObject();
+                               if (!hereLinkObj.GetHref().empty() && !hereLinkObj.GetId().empty())
+                               {
+                                       m_PlaceList.push_back(mapsPlace);
+                                       isPending = true;
+                                       StartPlaceDetailsInternal(hereLinkObj.GetHref().c_str());
+                                       MAPS_LOGD("Add maps_place_h to the pending list. id=%s", hereLinkObj.GetId().data());
+                               }
+                       }
+               }
+
+               if (!isPending) {
+                       m_nReplyIdx++;
+                       m_PlaceList.push_back(mapsPlace);
+               }
+       }
+
+       for (hereSearchIt = hereSearchList.begin();
+               hereSearchIt != hereSearchList.end() && !m_bCanceled;
+               hereSearchIt++)
+       {
+               error = maps_place_create(&mapsPlace);
+
+               if(error == MAPS_ERROR_NONE)
+               {
+                       is_valid = false;
+
+                       // title, uri, szId
+                       hereLinkObj = hereSearchIt->GetLinkObject();
+
+                       if (!hereLinkObj.GetTitle().empty())
+                       {
+                               sub_error = maps_place_set_name(mapsPlace,
+                                               (char*)hereLinkObj.GetTitle().c_str());
+                               is_valid |= (sub_error == MAPS_ERROR_NONE);
+                       }
+
+                       if (!hereLinkObj.GetHref().empty())
+                       {
+                               sub_error = maps_place_set_uri(mapsPlace,
+                                               (char*)hereLinkObj.GetHref().c_str());
+                               is_valid |= (sub_error == MAPS_ERROR_NONE);
+                       }
+
+                       if (!hereLinkObj.GetId().empty())
+                       {
+                               sub_error = maps_place_set_id(mapsPlace,
+                                               (char*)hereLinkObj.GetId().c_str());
+                               is_valid |= (sub_error == MAPS_ERROR_NONE);
+                       }
+                       /* icon */
+                       /* type */
+
+                       if (!is_valid)
+                               error = MAPS_ERROR_NOT_FOUND;
+               }
+
+               m_PlaceList.push_back(mapsPlace);
+               m_nReplyIdx++;
+       }
+
+
+       if (m_nReplyIdx == m_nReplyCnt - 1)
+       {
+               __sortList(m_PlaceList);
+       
+               m_nReplyIdx = 0;
+               while (m_nReplyIdx < m_nReplyCnt && !m_bCanceled && !m_PlaceList.empty())
+               {
+                       mapsPlace = m_PlaceList.front();
+                       m_PlaceList.pop_front();
+
+                       /* callback function */
+                       if (((maps_service_search_place_cb)m_pCbFunc)((maps_error_e)error, m_nReqId,
+                               m_nReplyIdx++, m_nReplyCnt, mapsPlace, m_pUserData) == FALSE)
+                       {
+                               break;
+                       }
+               }
+               delete this;
+       }
+}
+
+void HerePlace::OnPlaceDetailsReply (const PlaceDetailsReply &Reply)
+{
+       if (m_bCanceled) /* ignore call back if it was cancelled. */
+       {
+               delete this;
+               return;
+       }
+
+       if (m_nReplyCnt == 0)
+               m_nReplyCnt = 1;
+
+       PlaceDetails herePlace = Reply.GetPlaceDetails();
+       maps_place_h mapsPlace = NULL;
+       int error = MAPS_ERROR_NONE, sub_error;
+       bool is_valid, isPending = false;
+       char *placeId;
+       int placeIdLen;
+
+       /* Finding maps_place_h which is already pending since DiscoverReply */
+       PlaceList::iterator it;
+       for (it = m_PlaceList.begin(); it != m_PlaceList.end(); it++)
+       {
+               if (maps_place_get_id(*it, &placeId) == MAPS_ERROR_NONE)
+               {
+                       placeIdLen = strlen(placeId);
+                       if(!herePlace.GetPlaceId().compare(0, placeIdLen, placeId))
+                       {
+                               mapsPlace = *it;
+                               isPending = true;
+                               g_free(placeId);
+                               MAPS_LOGD("Found maps_place_h (%p) which is pending since DiscoveryReply", mapsPlace);
+                               break;
+                       }
+               }
+               g_free(placeId);
+       }
+
+       /* If not found, create new handle */
+       if (!mapsPlace)
+               error = maps_place_create(&mapsPlace);
+
+       if (error == MAPS_ERROR_NONE)
+       {
+               is_valid = false;
+
+               /* name */
+               if (!herePlace.GetName().empty())
+               {
+                       sub_error = maps_place_set_name(mapsPlace, (char*)herePlace.GetName().c_str());
+                       is_valid |= (sub_error == MAPS_ERROR_NONE);
+               }
+
+               /* id */
+               if (!herePlace.GetPlaceId().empty())
+               {
+                       sub_error = maps_place_set_id(mapsPlace, (char*)herePlace.GetPlaceId().c_str());
+                       is_valid |= (sub_error == MAPS_ERROR_NONE);
+               }
+
+               /* view */
+               if (!herePlace.GetView().empty())
+               {
+                       sub_error = maps_place_set_uri(mapsPlace, (char*)herePlace.GetView().c_str());
+                       is_valid |= (sub_error == MAPS_ERROR_NONE);
+               }
+
+               if (is_valid)
+               {
+                       /* icon */
+                       /* maps not supported // herePlace.GetIconPath(); */
+
+                       /* location */
+                       ProcessPlaceLocation(herePlace, mapsPlace);
+
+                       ProcessPlaceContact(herePlace, mapsPlace);
+
+                       ProcessPlaceCategory(herePlace, mapsPlace);
+
+                       /* tags */
+                       /* maps & here not supported */
+
+                       ProcessPlaceImage(herePlace, mapsPlace);
+
+                       ProcessPlaceDetails(herePlace, mapsPlace);
+
+                       ProcessPlaceReviews(herePlace, mapsPlace);
+
+                       ProcessPlaceRatings(herePlace, mapsPlace);
+
+                       ProcessPlaceRated(herePlace, mapsPlace);
+               }
+               else
+               {
+                       error = MAPS_ERROR_NOT_FOUND;
+               }
+       }
+
+       if (!isPending)
+               m_PlaceList.push_back(mapsPlace);
+
+       m_nReplyIdx++;
+
+
+       if (m_nReplyIdx == m_nReplyCnt - 1)
+       {
+               __sortList(m_PlaceList);
+       
+               m_nReplyIdx = 0;
+               while (m_nReplyIdx < m_nReplyCnt && !m_bCanceled && !m_PlaceList.empty())
+               {
+                       mapsPlace = m_PlaceList.front();
+                       m_PlaceList.pop_front();
+
+                       /* callback function */
+                       if (((maps_service_search_place_cb)m_pCbFunc)((maps_error_e)error, m_nReqId,
+                               m_nReplyIdx++, m_nReplyCnt, mapsPlace, m_pUserData) == FALSE)
+                       {
+                               break;
+                       }
+               }
+               delete this;
+       }
+}
+
+void HerePlace::ProcessPlaceLocation(PlaceDetails herePlace, maps_place_h mapsPlace)
+{
+       GeoLocation hereLocation = herePlace.GetLocation();
+
+       /* position */
+       GeoCoordinates hereCoord = hereLocation.GetDisplayPosition();
+       maps_coordinates_h mapsCoord;
+
+       if (maps_coordinates_create(hereCoord.GetLatitude(),
+               hereCoord.GetLongitude(), &mapsCoord) == MAPS_ERROR_NONE)
+       {
+               maps_place_set_location(mapsPlace, mapsCoord);
+               maps_coordinates_destroy(mapsCoord);
+       }
+
+       /* address */
+       Address hereAddr = hereLocation.GetAddress();
+       maps_address_h mapsAddr;
+       int error;
+       bool is_valid;
+
+       if (maps_address_create(&mapsAddr) == MAPS_ERROR_NONE)
+       {
+               is_valid = false;
+
+               if (!hereAddr.GetHouseNumber().empty())
+               {
+                       error = maps_address_set_building_number(mapsAddr,
+                                       hereAddr.GetHouseNumber().c_str());
+                       is_valid |= (error == MAPS_ERROR_NONE);
+               }
+
+               if (!hereAddr.GetStreet().empty())
+               {
+                       error = maps_address_set_street(mapsAddr, hereAddr.GetStreet().c_str());
+                       is_valid |= (error == MAPS_ERROR_NONE);
+               }
+
+               if (!hereAddr.GetDistrict().empty())
+               {
+                       error = maps_address_set_district(mapsAddr, hereAddr.GetDistrict().c_str());
+                       is_valid |= (error == MAPS_ERROR_NONE);
+               }
+
+               if (!hereAddr.GetCity().empty())
+               {
+                       error = maps_address_set_city(mapsAddr, hereAddr.GetCity().c_str());
+                       is_valid |= (error == MAPS_ERROR_NONE);
+               }
+
+               if (!hereAddr.GetState().empty())
+               {
+                       error = maps_address_set_state(mapsAddr, hereAddr.GetState().c_str());
+                       is_valid |= (error == MAPS_ERROR_NONE);
+               }
+
+               if (!hereAddr.GetCountry().empty())
+               {
+                       error = maps_address_set_country(mapsAddr, hereAddr.GetCountry().c_str());
+                       is_valid |= (error == MAPS_ERROR_NONE);
+               }
+
+               if (!hereAddr.GetCountryCode().empty())
+               {
+                       error = maps_address_set_country_code(mapsAddr, hereAddr.GetCountryCode().c_str());
+                       is_valid |= (error == MAPS_ERROR_NONE);
+               }
+
+               if (!hereAddr.GetCounty().empty())
+               {
+                       error = maps_address_set_county(mapsAddr, hereAddr.GetCounty().c_str());
+                       is_valid |= (error == MAPS_ERROR_NONE);
+               }
+
+               if (!hereAddr.GetPostalCode().empty())
+               {
+                       error = maps_address_set_postal_code(mapsAddr, hereAddr.GetPostalCode().c_str());
+                       is_valid |= (error == MAPS_ERROR_NONE);
+               }
+
+               if (!hereAddr.GetLabel().empty())
+               {
+                       error = maps_address_set_freetext(mapsAddr, hereAddr.GetLabel().c_str());
+                       is_valid |= (error == MAPS_ERROR_NONE);
+               }
+
+               if (is_valid)
+               {
+                       maps_place_set_address(mapsPlace, mapsAddr);
+               }
+               maps_address_destroy(mapsAddr);
+       }
+}
+
+
+void HerePlace::ProcessPlaceContact(PlaceDetails herePlace, maps_place_h mapsPlace)
+{
+       /* contact */
+       ContactDetailsList hereContList = herePlace.GetContactDetails();
+       ContactDetailsList::iterator hereCont;
+       maps_item_list_h mapsContList;
+       maps_place_contact_h mapsCont;
+       int error;
+       bool is_valid;
+
+       if (hereContList.empty()) return;
+
+       if (maps_item_list_create(&mapsContList) != MAPS_ERROR_NONE) return;
+
+       for (hereCont = hereContList.begin(); hereCont != hereContList.end(); hereCont++)
+       {
+               if (maps_place_contact_create(&mapsCont) != MAPS_ERROR_NONE) continue;
+
+               is_valid = false;
+
+               if (!hereCont->GetLabel().empty())
+               {
+                       error = maps_place_contact_set_label(mapsCont,
+                               (char*)hereCont->GetLabel().c_str());
+                       is_valid |= (error == MAPS_ERROR_NONE);
+               }
+
+               if (!hereCont->GetValue().empty())
+               {
+                       error = maps_place_contact_set_value(mapsCont,
+                               (char*)hereCont->GetValue().c_str());
+                       is_valid |= (error == MAPS_ERROR_NONE);
+               }
+
+               if (!hereCont->GetContactType().empty())
+               {
+                       error = maps_place_contact_set_type(mapsCont,
+                               (char*)hereCont->GetContactType().c_str());
+                       is_valid |= (error == MAPS_ERROR_NONE);
+               }
+
+               if (is_valid)
+               {
+                       maps_item_list_append(mapsContList, mapsCont,
+                               maps_place_contact_clone);
+               }
+               maps_place_contact_destroy(mapsCont);
+       }
+
+       if (maps_item_list_items(mapsContList))
+       {
+               maps_place_set_contacts(mapsPlace, mapsContList);
+               maps_item_list_remove_all(mapsContList, maps_place_contact_destroy);
+       }
+       maps_item_list_destroy(mapsContList);
+}
+
+void HerePlace::ProcessPlaceCategory(PlaceDetails herePlace, maps_place_h mapsPlace)
+{
+       CategoryList hereCateList = herePlace.GetCategories();
+       CategoryList::iterator hereCate;
+       maps_item_list_h mapsCateList;
+       maps_place_category_h mapsCate;
+       int error;
+       bool is_valid = false;
+
+       if (hereCateList.empty()) return;
+
+       if (maps_item_list_create(&mapsCateList) != MAPS_ERROR_NONE) return;
+
+       // maps-service supports only one category
+       hereCate = hereCateList.begin();
+       if (maps_place_category_create(&mapsCate) == MAPS_ERROR_NONE)
+       {
+               if (!hereCate->GetCategoryId().ToString().empty())
+               {
+                       error = maps_place_category_set_id(mapsCate,
+                               hereCate->GetCategoryId().ToString().c_str());
+                       is_valid |= (error == MAPS_ERROR_NONE);
+               }
+
+               if (!hereCate->GetTitle().empty())
+               {
+                       error = maps_place_category_set_name(mapsCate,
+                               hereCate->GetTitle().c_str());
+                       is_valid |= (error == MAPS_ERROR_NONE);
+               }
+
+               if (!hereCate->GetHref().empty())
+               {
+                       error = maps_place_category_set_url(mapsCate,
+                               hereCate->GetHref().c_str());
+                       is_valid |= (error == MAPS_ERROR_NONE);
+               }
+
+               if (is_valid)
+               {
+                       maps_item_list_append(mapsCateList, mapsCate, maps_place_category_clone);
+               }
+               maps_place_category_destroy(mapsCate);
+       }
+
+       if (maps_item_list_items(mapsCateList))
+       {
+               maps_place_set_categories(mapsPlace, mapsCateList);
+               maps_item_list_remove_all(mapsCateList, maps_place_category_destroy);
+       }
+       maps_item_list_destroy(mapsCateList);
+}
+
+void HerePlace::ProcessPlaceImage(PlaceDetails herePlace, maps_place_h mapsPlace)
+{ 
+       ImageContentList hereImageList = herePlace.GetImageContent();
+       ImageContentList::iterator hereImage;
+       maps_item_list_h mapsImageList;
+       maps_place_image_h mapsImage;
+       maps_place_link_object_h mapsImageUser;
+       LinkObject hereImageUser;
+       int error;
+       bool is_valid, is_valid2;
+
+       if (hereImageList.empty()) return;
+
+       if (maps_item_list_create(&mapsImageList) != MAPS_ERROR_NONE) return;
+
+       for (hereImage = hereImageList.begin(); hereImage != hereImageList.end(); hereImage++)
+       {
+               if (maps_place_image_create(&mapsImage) != MAPS_ERROR_NONE) continue;
+
+               is_valid = false;
+
+               /* here not supported
+               // maps_place_image_set_height(maps_place_image_h mapsPlace, const int height); */
+
+               /* here not supported
+               // maps_place_image_set_media(maps_place_image_h mapsPlace, maps_place_media_h media); */
+
+               if (!hereImage->GetSource().empty())
+               {
+                       error = maps_place_image_set_url(mapsImage, (char*)hereImage->GetSource().c_str());
+                       is_valid |= (error == MAPS_ERROR_NONE);
+               }
+
+               if (!hereImage->GetImageId().empty())
+               {
+                       error = maps_place_image_set_id(mapsImage, (char*)hereImage->GetImageId().c_str());
+                       is_valid |= (error == MAPS_ERROR_NONE);
+               }
+
+               hereImageUser = hereImage->GetUser();
+               if (maps_place_link_object_create(&mapsImageUser) == MAPS_ERROR_NONE)
+               {
+                       is_valid2 = false;
+
+                       if (!hereImageUser.GetId().empty())
+                       {
+                               error = maps_place_link_object_set_id(mapsImageUser,
+                                               (char*)hereImageUser.GetId().c_str());
+                               is_valid2 |= (error == MAPS_ERROR_NONE);
+                       }
+
+                       if (!hereImageUser.GetTitle().empty())
+                       {
+                               error = maps_place_link_object_set_name(mapsImageUser,
+                                               (char*)hereImageUser.GetTitle().c_str());
+                               is_valid2 |= (error == MAPS_ERROR_NONE);
+                       }
+
+                       if (!hereImageUser.GetHref().empty())
+                       {
+                               error = maps_place_link_object_set_string(mapsImageUser,
+                                               (char*)hereImageUser.GetHref().c_str());
+                               is_valid2 |= (error == MAPS_ERROR_NONE);
+                       }
+
+                       if (!hereImageUser.GetType().empty())
+                       {
+                               error = maps_place_link_object_set_type(mapsImageUser,
+                                               (char*)hereImageUser.GetType().c_str());
+                               is_valid2 |= (error == MAPS_ERROR_NONE);
+                       }
+
+                       if (is_valid2)
+                       {
+                               maps_place_image_set_user_link(mapsImage, mapsImageUser);
+                               is_valid |= is_valid2;
+                       }
+                       maps_place_link_object_destroy(mapsImageUser);
+               }
+
+               if (is_valid)
+               {
+                       maps_item_list_append(mapsImageList, mapsImage, maps_place_image_clone);
+               }
+               maps_place_image_destroy(mapsImage);
+       }
+
+       if (maps_item_list_items(mapsImageList))
+       {
+               maps_place_set_images(mapsPlace, mapsImageList);
+               maps_item_list_remove_all(mapsImageList, maps_place_image_destroy);
+       }
+       maps_item_list_destroy(mapsImageList);
+}
+
+void HerePlace::ProcessPlaceDetails(PlaceDetails herePlace, maps_place_h mapsPlace)
+{
+       EditorialContentList hereEditList = herePlace.GetEditorialContent();
+       EditorialContentList::iterator hereEdit;
+       maps_item_list_h mapsEditList;
+       maps_place_editorial_h mapsEdit;
+       int error;
+       bool is_valid;
+
+       if (hereEditList.empty()) return;
+
+       if (maps_item_list_create(&mapsEditList) != MAPS_ERROR_NONE) return;
+
+       for (hereEdit = hereEditList.begin(); hereEdit != hereEditList.end(); hereEdit++)
+       {
+               if (maps_place_editorial_create(&mapsEdit) != MAPS_ERROR_NONE) continue;
+
+               is_valid = false;
+
+               if (!hereEdit->GetDescription().empty())
+               {
+                       error = maps_place_editorial_set_description(mapsEdit,
+                               (char*)hereEdit->GetDescription().c_str());
+                       is_valid |= (error == MAPS_ERROR_NONE);
+               }
+
+               if (!hereEdit->GetLanguage().empty())
+               {
+                       error = maps_place_editorial_set_language(mapsEdit,
+                               (char*)hereEdit->GetLanguage().c_str());
+                       is_valid |= (error == MAPS_ERROR_NONE);
+               }
+
+               /* maps_place_editorial_set_media(mapsEdit, maps_place_media_h media); */
+
+               if (is_valid)
+               {
+                       maps_item_list_append(mapsEditList, mapsEdit, maps_place_editorial_clone);
+               }
+               maps_place_editorial_destroy(mapsEdit);
+       }
+
+       if (maps_item_list_items(mapsEditList))
+       {
+               maps_place_set_editorials(mapsPlace, mapsEditList);
+               maps_item_list_remove_all(mapsEditList, maps_place_editorial_destroy);
+       }
+       maps_item_list_destroy(mapsEditList);
+}
+
+void HerePlace::ProcessPlaceReviews(PlaceDetails herePlace, maps_place_h mapsPlace)
+{
+       ReviewContentList hereReviewList = herePlace.GetReviewContent();
+       ReviewContentList::iterator hereReview;
+       maps_place_review_h mapsReview;
+       maps_item_list_h mapsReviewList;
+       LinkObject hereReviewUser;
+       maps_place_link_object_h mapsReviewUser;
+       int error;
+       bool is_valid, is_valid2;
+
+       if (hereReviewList.empty()) return;
+
+       if (maps_item_list_create(&mapsReviewList) != MAPS_ERROR_NONE) return;
+
+       for (hereReview = hereReviewList.begin(); hereReview != hereReviewList.end(); hereReview++)
+       {
+               if (maps_place_review_create(&mapsReview) != MAPS_ERROR_NONE) continue;
+
+               is_valid = false;
+
+               if (!hereReview->GetDateTime().empty())
+               {
+                       error = maps_place_review_set_date(mapsReview,
+                               (char*)hereReview->GetDateTime().c_str());
+                       is_valid |= (error == MAPS_ERROR_NONE);
+               }
+
+               if (!hereReview->GetDescription().empty())
+               {
+                       error = maps_place_review_set_description(mapsReview,
+                               (char*)hereReview->GetDescription().c_str());
+                       is_valid |= (error == MAPS_ERROR_NONE);
+               }
+
+               if (!hereReview->GetLanguage().empty())
+               {
+                       error = maps_place_review_set_language(mapsReview,
+                               (char*)hereReview->GetLanguage().c_str());
+                       is_valid |= (error == MAPS_ERROR_NONE);
+               }
+
+               /* maps_place_review_set_media(mapsReview, maps_place_media_h media) */
+
+               maps_place_review_set_rating(mapsReview, hereReview->GetRating());
+
+               if (!hereReview->GetTitle().empty())
+               {
+                       error = maps_place_review_set_title(mapsReview,
+                               (char*)hereReview->GetTitle().c_str());
+                       is_valid |= (error == MAPS_ERROR_NONE);
+               }
+
+               hereReviewUser = hereReview->GetUser();
+               if (maps_place_link_object_create(&mapsReviewUser) == MAPS_ERROR_NONE)
+               {
+                       is_valid2 = false;
+
+                       if (!hereReviewUser.GetId().empty())
+                       {
+                               error = maps_place_link_object_set_id(mapsReviewUser,
+                                       (char*)hereReviewUser.GetId().c_str());
+                               is_valid2 |= (error == MAPS_ERROR_NONE);
+                       }
+
+                       if (!hereReviewUser.GetTitle().empty())
+                       {
+                               error = maps_place_link_object_set_name(mapsReviewUser,
+                                       (char*)hereReviewUser.GetTitle().c_str());
+                               is_valid2 |= (error == MAPS_ERROR_NONE);
+                       }
+
+                       if (!hereReviewUser.GetHref().empty())
+                       {
+                               error = maps_place_link_object_set_string(mapsReviewUser,
+                                       (char*)hereReviewUser.GetHref().c_str());
+                               is_valid2 |= (error == MAPS_ERROR_NONE);
+                       }
+
+                       if (!hereReviewUser.GetType().empty())
+                       {
+                               error = maps_place_link_object_set_type(mapsReviewUser,
+                                       (char*)hereReviewUser.GetType().c_str());
+                               is_valid2 |= (error == MAPS_ERROR_NONE);
+                       }
+
+                       if (is_valid2)
+                       {
+                               maps_place_review_set_user_link(mapsReview, mapsReviewUser);
+                               is_valid |= is_valid2;
+                       }
+                       maps_place_link_object_destroy(mapsReviewUser);
+               }
+
+               if (is_valid)
+               {
+                       maps_item_list_append(mapsReviewList, mapsReview, maps_place_review_clone);
+               }
+               maps_place_review_destroy(mapsReview);
+       }
+
+       if (maps_item_list_items(mapsReviewList))
+       {
+               maps_place_set_reviews(mapsPlace, mapsReviewList);
+               maps_item_list_remove_all(mapsReviewList, maps_place_review_destroy);
+       }
+       maps_item_list_destroy(mapsReviewList);
+}
+
+void HerePlace::ProcessPlaceRatings(PlaceDetails herePlace, maps_place_h mapsPlace)
+{
+       Ratings hereRating = herePlace.GetRatings();
+       maps_place_rating_h mapsRating;
+
+       if (maps_place_rating_create(&mapsRating) != MAPS_ERROR_NONE) return;
+
+       maps_place_rating_set_average(mapsRating, hereRating.GetAverage());
+       maps_place_rating_set_count(mapsRating, hereRating.GetCount());
+       maps_place_set_rating(mapsPlace, mapsRating);
+       maps_place_rating_destroy(mapsRating);
+}
+
+void HerePlace::ProcessPlaceRated(PlaceDetails herePlace, maps_place_h mapsPlace)
+{
+       RelatedItem hereRelated = herePlace.GetRelatedItem();
+       maps_place_link_object_h mapsRelated;
+       int error;
+       bool is_valid = false;
+
+       if (maps_place_link_object_create(&mapsRelated) != MAPS_ERROR_NONE) return;
+
+       //need to check if GetId() exist
+       //maps_place_link_object_set_id(mapsRelated, hereRelated.GetId());
+
+       if (!hereRelated.GetTitle().empty())
+       {
+               error = maps_place_link_object_set_name(mapsRelated,
+                       (char*)hereRelated.GetTitle().c_str());
+               is_valid |= (error == MAPS_ERROR_NONE);
+       }
+
+       if (!hereRelated.GetHref().empty())
+       {
+               error = maps_place_link_object_set_string(mapsRelated,
+                       (char*)hereRelated.GetHref().c_str());
+               is_valid |= (error == MAPS_ERROR_NONE);
+       }
+
+       if (!hereRelated.GetType().empty())
+       {
+               error = maps_place_link_object_set_type(mapsRelated,
+                       (char*)hereRelated.GetType().c_str());
+               is_valid |= (error == MAPS_ERROR_NONE);
+       }
+
+       if (is_valid)
+       {
+               maps_place_set_related_link(mapsPlace, mapsRelated);
+       }
+       maps_place_link_object_destroy(mapsRelated);
+}
+
+bool HerePlace::__compareWithTitle(const maps_place_h &item1, const maps_place_h &item2)
+{
+       bool result = false;
+       char *str1 = NULL, *str2 = NULL;
+
+       if (maps_place_get_name(item1, &str1) == MAPS_ERROR_NONE &&
+               maps_place_get_name(item2, &str2) == MAPS_ERROR_NONE)
+       {
+               result = (strcmp(str1, str2) < 0);
+       }
+       g_free(str1);
+       g_free(str2);
+       return result;
+}
+
+bool HerePlace::__compareWithId(const maps_place_h &item1, const maps_place_h &item2)
+{
+       bool result = false;
+       char *str1 = NULL, *str2 = NULL;
+
+       if (maps_place_get_id(item1, &str1) == MAPS_ERROR_NONE &&
+               maps_place_get_id(item2, &str2) == MAPS_ERROR_NONE)
+       {
+               result = (strcmp(str1, str2) < 0);
+       }
+       g_free(str1);
+       g_free(str2);
+       return result;
+}
+
+bool HerePlace::__compareWithDistance(const maps_place_h &item1, const maps_place_h &item2)
+{
+       bool result = false;
+       int num1 = 0, num2 = 0;
+
+       if (maps_place_get_distance(item1, &num1) == MAPS_ERROR_NONE &&
+               maps_place_get_distance(item2, &num2) == MAPS_ERROR_NONE)
+       {
+               result = (num1 < num2);
+       }
+       return result;
+}
+
+bool HerePlace::__compareWithRating(const maps_place_h &item1, const maps_place_h &item2)
+{
+       bool result = false;
+       maps_place_rating_h rat1 = NULL, rat2 = NULL;
+       double num1 = 0, num2 = 0;      
+
+       if (maps_place_get_rating(item1, &rat1) == MAPS_ERROR_NONE &&
+               maps_place_get_rating(item2, &rat2) == MAPS_ERROR_NONE)
+       {
+               if (maps_place_rating_get_average(rat1, &num1) == MAPS_ERROR_NONE &&
+                       maps_place_rating_get_average(rat2, &num2) == MAPS_ERROR_NONE)
+               {
+                       result = (num1 > num2);
+               }
+       }
+       maps_place_rating_destroy(rat1);
+       maps_place_rating_destroy(rat2);
+       return result;
+}
+
+bool HerePlace::__compareWithCategoryCb(int index, int total,
+                                        maps_place_category_h category,
+                                        void *user_data)
+{
+       user_data = category;
+       return false;
+}
+
+bool HerePlace::__compareWithCategory(const maps_place_h &item1, const maps_place_h &item2)
+{
+       bool result = false;
+       maps_place_category_h cat1 = NULL, cat2 = NULL;
+       char *str1 = NULL, *str2 = NULL;
+
+       maps_place_foreach_category(item1, __compareWithCategoryCb, &cat1);
+       maps_place_foreach_category(item2, __compareWithCategoryCb, &cat2);
+
+       if (maps_place_category_get_id(item1, &str1) == MAPS_ERROR_NONE &&
+               maps_place_category_get_id(item2, &str2) == MAPS_ERROR_NONE)
+       {
+               result = (strcmp(str1, str2) < 0);
+       }
+       maps_place_category_destroy(item1);
+       maps_place_category_destroy(item2);
+       g_free(str1);
+       g_free(str2);
+       return result;
+}
+
+void HerePlace::__sortList(PlaceList &list)
+{
+       if (!m_szSortBy) return;
+
+       if (!strcmp(m_szSortBy, "name") || !strcmp(m_szSortBy, "title"))
+       {
+               std::sort(list.begin(), list.end(), __compareWithTitle);
+       }
+       else if (!strcmp(m_szSortBy, "id"))
+       {
+               std::sort(list.begin(), list.end(), __compareWithId);
+       }
+       else if (!strcmp(m_szSortBy, "distance"))
+       {
+               std::sort(list.begin(), list.end(), __compareWithDistance);
+       }
+       else if (!strcmp(m_szSortBy, "rate") || !strcmp(m_szSortBy, "rating"))
+       {
+               std::sort(list.begin(), list.end(), __compareWithRating);
+       }
+       else if (!strcmp(m_szSortBy, "category"))
+       {
+               std::sort(list.begin(), list.end(), __compareWithCategory);
+       }
+}
+
+HERE_PLUGIN_END_NAMESPACE
diff --git a/src/here/here_place.h b/src/here/here_place.h
new file mode 100755 (executable)
index 0000000..febdc24
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LOCATION_HERE_PLACE_H_
+#define _LOCATION_HERE_PLACE_H_
+
+#include <deque>
+
+//plug-in header
+#include "here_manager.h"
+
+//maps-service header
+#include <maps_place_plugin.h>
+#include <maps_place_rating_plugin.h>
+#include <maps_place_contact_plugin.h>
+#include <maps_place_image_plugin.h>
+#include <maps_place_link_object_plugin.h>
+#include <maps_place_editorial_plugin.h>
+#include <maps_place_review_plugin.h>
+
+//map engine header
+#include <finder/DiscoveryQuery.h>
+#include <finder/PlaceDetailsQuery.h>
+#include <finder/FinderQueryListener.h>
+#include <finder/DiscoveryReply.h>
+#include <finder/PlaceDetailsReply.h>
+#include <finder/PlaceDetails.h>
+#include <finder/CategoryId.h>
+#include <finder/LinkObject.h>
+#include <finder/Ratings.h>
+#include <finder/RelatedItem.h>
+#include <common/GeoLocation.h>
+#include <common/Address.h>
+
+
+HERE_PLUGIN_BEGIN_NAMESPACE
+
+using namespace HERE_MAPS_NAMESPACE_PREFIX;
+
+class HerePlace
+: public HereBase
+, public FinderQueryListener
+{
+public:
+       typedef std::deque<maps_place_h> PlaceList;
+
+       /**
+        *This is the default constructor for Place.
+        */
+
+       HerePlace(void *pCbFunc, void *pUserData, int nReqId);
+
+       /**
+        *This is the default destructor for Place.
+        */
+
+       ~HerePlace();
+
+       here_error_e PrepareDiscoveryQuery();
+       here_error_e PrepareDiscoveryPreference(maps_preference_h hPref);
+       here_error_e PrepareDiscoveryFilter(maps_place_filter_h hFilter);
+
+       here_error_e StartDiscoveryPlace(maps_coordinates_h hCoord, int nDistance);
+       here_error_e StartDiscoveryPlaceByArea(maps_area_h hArea);
+       here_error_e StartDiscoveryPlaceByAddress(const char *szAddr, maps_area_h hArea);
+
+       here_error_e PreparePlaceDetailsQuery();
+       here_error_e PreparePlaceDetailsPreference(maps_preference_h hPref);
+       
+       here_error_e StartPlaceDetails(const char* szPlaceId);
+       here_error_e StartPlaceDetailsInternal(const char* szUrl);
+
+       virtual void OnDiscoverReply(const DiscoveryReply &Reply);
+       virtual void OnPlaceDetailsReply(const PlaceDetailsReply &Reply);
+
+private:
+       void ProcessPlaceLocation(PlaceDetails herePlace, maps_place_h mapsPlace);
+       void ProcessPlaceContact(PlaceDetails herePlace, maps_place_h mapsPlace);
+       void ProcessPlaceCategory(PlaceDetails herePlace, maps_place_h mapsPlace);
+       void ProcessPlaceImage(PlaceDetails herePlace, maps_place_h mapsPlace);
+       void ProcessPlaceDetails(PlaceDetails herePlace, maps_place_h mapsPlace);
+       void ProcessPlaceReviews(PlaceDetails herePlace, maps_place_h mapsPlace);
+       void ProcessPlaceRatings(PlaceDetails herePlace, maps_place_h mapsPlace);
+       void ProcessPlaceRated(PlaceDetails herePlace, maps_place_h mapsPlace);
+
+       void __sortList(PlaceList &list);
+       static bool __compareWithTitle(const maps_place_h &item1, const maps_place_h &item2);
+       static bool __compareWithId(const maps_place_h &item1, const maps_place_h &item2);
+       static bool __compareWithType(const maps_place_h &item1, const maps_place_h &item2);
+       static bool __compareWithDistance(const maps_place_h &item1, const maps_place_h &item2);
+       static bool __compareWithRating(const maps_place_h &item1, const maps_place_h &item2);
+       static bool __compareWithCategory(const maps_place_h &item1, const maps_place_h &item2);
+       static bool __compareWithCategoryCb(int index, int total, maps_place_category_h category,
+                                        void *user_data);
+
+       DiscoveryQuery* m_pDiscoveryQuery;
+       PlaceDetailsQuery* m_pPlaceDetailsQuery;
+       int m_nReplyCnt;
+       int m_nReplyIdx;
+       char *m_szSortBy;
+
+       PlaceList m_PlaceList;;
+
+       static const bool __sending_place_details_query_automatically = TRUE;
+};
+
+HERE_PLUGIN_END_NAMESPACE
+
+#endif //_LOCATION_HERE_PLACE_H_
diff --git a/src/here/here_revgeocode.cpp b/src/here/here_revgeocode.cpp
new file mode 100755 (executable)
index 0000000..1e7d273
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "here_revgeocode.h"
+
+HERE_PLUGIN_BEGIN_NAMESPACE
+
+HereRevGeocode::HereRevGeocode(void* pCbFunc, void* pUserData, int nReqId)
+: m_geoCoord(0,0,0)
+{
+       m_pQuery = NULL;
+       m_pCbFunc = pCbFunc;
+       m_pUserData = pUserData;
+       m_nReqId = nReqId;
+}
+
+HereRevGeocode::~HereRevGeocode()
+{
+       if (m_pQuery)
+       {
+               delete m_pQuery;
+               m_pQuery = NULL;
+       }
+}
+
+here_error_e HereRevGeocode::PrepareQuery()
+{
+       if (m_pQuery)
+               return HERE_ERROR_PERMISSION_DENIED;
+
+       m_pQuery = new ReverseGeoCoderQuery();
+
+       if (!m_pQuery)
+               return HERE_ERROR_OUT_OF_MEMORY;
+       else
+               return HERE_ERROR_NONE;
+}
+
+here_error_e HereRevGeocode::PreparePreference(maps_preference_h hPref)
+{
+       if (!m_pQuery)
+               return HERE_ERROR_OUT_OF_MEMORY;
+
+       if (!hPref)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       int ret;
+       char *szLanguage;
+       ret = maps_preference_get_language(hPref, &szLanguage);
+       if (ret == MAPS_ERROR_NONE && szLanguage && *szLanguage)
+               m_pQuery->AppendPreferredLanguage(szLanguage);
+       g_free(szLanguage);
+
+       int nMaxResults;
+       ret = maps_preference_get_max_results(hPref, &nMaxResults);
+       if (ret == MAPS_ERROR_NONE)
+               m_pQuery->SetMaxResults((size_t)nMaxResults);
+
+       return HERE_ERROR_NONE;
+}
+
+here_error_e HereRevGeocode::PreparePosition(double dLat, double dLng)
+{
+       if (!m_pQuery)
+               return HERE_ERROR_OUT_OF_MEMORY;
+
+       GeoCoordinates geoCoord(dLat, dLng);
+       if (!HereUtils::IsValid(geoCoord))
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       m_pQuery->SetProximity(geoCoord, 0);
+       m_pQuery->SetMode(ReverseGeoCoderQuery::RM_RetrieveAddresses);
+
+       return HERE_ERROR_NONE;
+}
+
+here_error_e HereRevGeocode::StartRevGeocode(maps_item_hashtable_h hPref)
+{
+       if (!m_pQuery)
+               return HERE_ERROR_OUT_OF_MEMORY;
+
+       m_nRestReqId = m_pQuery->Execute(*this, NULL);
+
+       return (m_nRestReqId > 0 ? HERE_ERROR_NONE : HERE_ERROR_INVALID_OPERATION);
+}
+
+void HereRevGeocode::OnGeoCoderReply(const GeoCoderReply& Reply)
+{
+       if (m_bCanceled) // ignore call back if it was cancelled.
+       {
+               delete this;
+               return;
+       }
+
+
+       int nResults = Reply.GetNumResults();
+       Result* pResult;
+       float fDistance, fShortestDistance = 0;
+       int nShortestIdx = -1;
+
+       for (size_t i = 0; i < (size_t)nResults; i++)
+       {
+               pResult = (Result*)Reply.GetResult(i);
+
+               if(pResult)
+               {
+                       fDistance = pResult->GetDistance();
+
+                       if (nShortestIdx < 0 || fDistance < fShortestDistance)
+                       {
+                               fShortestDistance = fDistance;
+                               nShortestIdx = i;
+                       }
+               }
+       }
+
+
+       if (nShortestIdx < 0)
+       {
+               ((maps_service_reverse_geocode_cb)m_pCbFunc)(MAPS_ERROR_NOT_FOUND,
+                       m_nReqId, 0, 1, NULL, m_pUserData);
+               delete this;
+               return;
+       }
+
+       maps_address_h hAddr = NULL;
+       maps_error_e error = (maps_error_e)maps_address_create(&hAddr);
+
+       if(error == MAPS_ERROR_NONE)
+       {
+               pResult = (Result*)Reply.GetResult(nShortestIdx);
+
+               if (pResult)
+               {
+                       Address tmpAddr = (pResult->GetLocation()).GetAddress();
+
+                       if(!tmpAddr.GetHouseNumber().empty())
+                               maps_address_set_building_number(hAddr, tmpAddr.GetHouseNumber().c_str());
+
+                       if(!tmpAddr.GetStreet().empty())
+                               maps_address_set_street(hAddr, tmpAddr.GetStreet().c_str());
+
+                       if(!tmpAddr.GetDistrict().empty())
+                               maps_address_set_district(hAddr, tmpAddr.GetDistrict().c_str());
+
+                       if(!tmpAddr.GetCity().empty())
+                               maps_address_set_city(hAddr, tmpAddr.GetCity().c_str());
+
+                       if(!tmpAddr.GetCounty().empty())
+                               maps_address_set_county(hAddr, tmpAddr.GetCounty().c_str());
+
+                       if(!tmpAddr.GetState().empty())
+                               maps_address_set_state(hAddr, tmpAddr.GetState().c_str());
+
+                       if(!tmpAddr.GetCountry().empty())
+                               maps_address_set_country(hAddr, tmpAddr.GetCountry().c_str());
+
+                       if(!tmpAddr.GetCountryCode().empty())
+                               maps_address_set_country_code(hAddr, tmpAddr.GetCountryCode().c_str());
+
+                       if(!tmpAddr.GetPostalCode().empty())
+                               maps_address_set_postal_code(hAddr, tmpAddr.GetPostalCode().c_str());
+
+                       if(!tmpAddr.GetLabel().empty())
+                               maps_address_set_freetext(hAddr, tmpAddr.GetLabel().c_str());
+               }
+       }
+
+       if (m_bCanceled)
+       {
+               maps_address_destroy(hAddr);
+       }
+       else
+       {
+               ((maps_service_reverse_geocode_cb)m_pCbFunc)(error, m_nReqId, 0, 1, hAddr, m_pUserData);
+       }
+
+       delete this;
+}
+
+HERE_PLUGIN_END_NAMESPACE
+
diff --git a/src/here/here_revgeocode.h b/src/here/here_revgeocode.h
new file mode 100755 (executable)
index 0000000..30f827f
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LOCATION_HERE_REV_GEOCODER_H_
+#define _LOCATION_HERE_REV_GEOCODER_H_
+
+//plug-in header
+#include "here_manager.h"
+
+#include <maps_coordinates.h>
+
+//map engine header
+#include <geocoder/ReverseGeoCoderQuery.h>
+#include <geocoder/GeoCoderQueryListener.h>
+#include <geocoder/GeoCoderReply.h>
+#include <geocoder/Result.h>
+#include <common/GeoLocation.h>
+#include <common/Address.h>
+
+HERE_PLUGIN_BEGIN_NAMESPACE
+
+using namespace HERE_MAPS_NAMESPACE_PREFIX;
+
+class HereRevGeocode
+: public HereBase
+, public GeoCoderQueryListener
+{
+public:
+       /**
+        *This is the default constructor for reverse Geocoder.
+        */
+
+       HereRevGeocode(void *pCbFunc, void *pUserData, int nReqId);
+
+       /**
+        *This is the default destructor for reverse Geocoder.
+        */
+
+       ~HereRevGeocode();
+
+
+       here_error_e PrepareQuery();
+       here_error_e PreparePreference(maps_preference_h hPref);
+       here_error_e PreparePosition(double dLat, double dLng);
+
+       here_error_e StartRevGeocode(maps_item_hashtable_h hPref);
+
+       virtual void OnGeoCoderReply(const GeoCoderReply& Reply);
+
+private:
+       ReverseGeoCoderQuery* m_pQuery;
+       GeoCoordinates m_geoCoord;
+};
+
+HERE_PLUGIN_END_NAMESPACE
+
+#endif //_LOCATION_HERE_REV_GEOCODER_H_
diff --git a/src/here/here_route.cpp b/src/here/here_route.cpp
new file mode 100755 (executable)
index 0000000..58cb5fe
--- /dev/null
@@ -0,0 +1,425 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "here_route.h"
+
+HERE_PLUGIN_BEGIN_NAMESPACE
+
+HereRoute::HereRoute(void *pCbFunc, void *pUserData, int nReqId)
+{
+       m_pQuery = NULL;
+
+       m_pCbFunc = pCbFunc;
+       m_pUserData = pUserData;
+       m_nReqId = nReqId;
+}
+
+HereRoute::~HereRoute()
+{
+       if (m_pQuery)
+       {
+               delete m_pQuery;
+               m_pQuery = NULL;
+       }
+}
+
+here_error_e HereRoute::PrepareQuery()
+{
+       if (m_pQuery)
+               return HERE_ERROR_PERMISSION_DENIED;
+
+       GeoCoordinates origCoord, destCoord;
+       m_pQuery = new GeoRouteQuery(origCoord, destCoord);
+
+       if (!m_pQuery)
+               return HERE_ERROR_OUT_OF_MEMORY;
+       else
+               return HERE_ERROR_NONE;
+}
+
+here_error_e HereRoute::PrepareWaypoint(maps_coordinates_h hOrigin, maps_coordinates_h hDestination)
+{
+       if (!m_pQuery)
+               return HERE_ERROR_OUT_OF_MEMORY;
+
+       if (!hOrigin || !hDestination)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+
+       const int nWaypointNum = 2;
+       maps_coordinates_h hWaypointList[nWaypointNum];
+       hWaypointList[0] = hOrigin;
+       hWaypointList[1] = hDestination;
+
+       return PrepareWaypoint(hWaypointList, nWaypointNum);
+}
+
+here_error_e HereRoute::PrepareWaypoint(const maps_coordinates_h* hWaypointList, int nWaypointNum)
+{
+       if (!m_pQuery)
+               return HERE_ERROR_OUT_OF_MEMORY;
+
+       if (!hWaypointList || nWaypointNum <= 0)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+       GeoCoordinateList hereCoordList;
+       GeoCoordinates hereCoord;
+       double dLatitude, dLongitude;
+
+       for (int index = 0; index < nWaypointNum; index++)
+       {
+               if (hWaypointList[index] != NULL) {
+                       maps_coordinates_get_latitude(hWaypointList[index], &dLatitude);
+                       maps_coordinates_get_longitude(hWaypointList[index], &dLongitude);
+
+                       //MAPS_LOGD("Waypoint --> Lat : %f, Long : %f", dLatitude, dLongitude);
+
+                       hereCoord = GeoCoordinates(dLatitude, dLongitude);
+
+                       if (!HereUtils::IsValid(hereCoord))
+                               return HERE_ERROR_INVALID_PARAMETER;
+
+                       hereCoordList.push_back(hereCoord);
+               }
+       }
+
+       m_pQuery->SetWaypoints(hereCoordList);
+
+       return HERE_ERROR_NONE;
+}
+
+here_error_e HereRoute::PreparePreference(maps_preference_h hPref)
+{
+       if (!m_pQuery)
+               return HERE_ERROR_OUT_OF_MEMORY;
+
+       if (!hPref)
+               return HERE_ERROR_INVALID_PARAMETER;
+
+/*
+       SegmentDetail aSegmentDetail;
+       ManeuverDetail aMneuverDetail;
+       m_pQuery->SetSegmentDetail(aSegmentDetail);
+       m_pQuery->SetManeuverDetail(aMneuverDetail);
+*/
+
+       /* transport mode */
+       maps_route_transport_mode_e eTransMode;
+       if (maps_preference_get_route_transport_mode(hPref, &eTransMode) == MAPS_ERROR_NONE)
+       {
+               m_pQuery->SetTravelModes(HereUtils::Convert(eTransMode));
+       }
+
+       /* eFeature */
+       maps_route_feature_e eFeature;
+       maps_route_feature_weight_e eFeatureWeight;
+       if (maps_preference_get_route_feature(hPref, &eFeature) == MAPS_ERROR_NONE &&
+           maps_preference_get_route_feature_weight(hPref, &eFeatureWeight) == MAPS_ERROR_NONE)
+       {
+               m_pQuery->SetFeatureWeight(HereUtils::Convert(eFeature),
+                       HereUtils::Convert(eFeatureWeight));
+       }
+
+       /* exclude areas */
+       char *szAreaToAvoid;
+       if (maps_preference_get(hPref, MAPS_ROUTE_RECT_AREA_TO_AVOID, &szAreaToAvoid) == MAPS_ERROR_NONE)
+       {
+               GeoBoundingBox gbBox;
+               GeoBoundingBoxList gbBoxList;
+               gbBoxList.push_back(HereUtils::Convert(szAreaToAvoid, gbBox));
+               m_pQuery->SetExcludeAreas(gbBoxList);
+               g_free(szAreaToAvoid);
+       }
+
+       /* optimization */
+       GeoRouteQuery::RouteOptimization hereOpt;
+       maps_route_optimization_e mapsOpt;
+       if (maps_preference_get_route_optimization(hPref, &mapsOpt) == MAPS_ERROR_NONE)
+       {
+               switch (mapsOpt)
+               {
+               case MAPS_ROUTE_TYPE_FASTEST:  hereOpt = GeoRouteQuery::RO_FastestRoute;  break;
+               case MAPS_ROUTE_TYPE_SHORTEST: hereOpt = GeoRouteQuery::RO_ShortestRoute; break;
+               default:                       hereOpt = GeoRouteQuery::RO_FastestRoute;  break;
+               }
+               m_pQuery->SetRouteOptimization(hereOpt);
+       }
+
+       /* Metric System */
+       GeoRouteQuery::MetricSystem eMetric;
+       maps_distance_unit_e eUnit;
+       if (maps_preference_get_distance_unit(hPref, &eUnit) == MAPS_ERROR_NONE)
+       {
+               switch (eUnit)
+               {
+               case MAPS_DISTANCE_UNIT_M:  eMetric = GeoRouteQuery::DIST_metric;   break;
+               case MAPS_DISTANCE_UNIT_KM: eMetric = GeoRouteQuery::DIST_metric;   break;
+               default:                    eMetric = GeoRouteQuery::DIST_imperial; break;
+               }
+               m_pQuery->SetMetricSystem(eMetric);
+       }
+
+       char *szViewBounds;
+       if (maps_preference_get(hPref, MAPS_ROUTE_GEOMETRY_BOUNDING_BOX, &szViewBounds) == MAPS_ERROR_NONE)
+       {
+               GeoBoundingBox gbBox;
+               HereUtils::Convert(szViewBounds, gbBox);
+               m_pQuery->SetViewBounds(gbBox);
+               g_free(szViewBounds);
+       }
+
+       return HERE_ERROR_NONE;
+}
+
+here_error_e HereRoute::StartRoute(void)
+{
+       if (!m_pQuery)
+               return HERE_ERROR_OUT_OF_MEMORY;
+
+       m_nRestReqId = m_pQuery->Execute(*this, NULL);
+
+       return (m_nRestReqId > 0 ? HERE_ERROR_NONE : HERE_ERROR_INVALID_OPERATION);
+}
+
+void HereRoute::OnRouteReply(const GeoRouteReply& Reply)
+{
+       if (m_bCanceled) // ignore call back if it was cancelled.
+       {
+               delete this;
+               return;
+       }
+
+       maps_route_h mapsRoute;
+       maps_error_e error;
+       GeoRouteList hereRouteList = Reply.GetRoutes();
+       int nReplyIdx = 0, nReplyNum = hereRouteList.size();
+       GeoRouteList::iterator hereRoute;
+
+       if (nReplyNum == 0)
+       {
+               ((maps_service_search_route_cb)m_pCbFunc)(MAPS_ERROR_NOT_FOUND, m_nReqId,
+                       0, 1, NULL, m_pUserData);
+               delete this;
+               return;
+       }
+
+       for (hereRoute = hereRouteList.begin() ; hereRoute != hereRouteList.end() ; hereRoute++)
+       {
+               error = (maps_error_e)maps_route_create(&mapsRoute);
+
+               if (error == MAPS_ERROR_NONE)
+               {
+                       /* route id */
+                       if (!hereRoute->GetRouteId().empty())
+                               maps_route_set_route_id(mapsRoute, (char*)hereRoute->GetRouteId().c_str());
+
+                       /* distance */
+                       maps_route_set_total_distance(mapsRoute, hereRoute->GetDistance());
+
+                       /* duration */
+                       maps_route_set_total_duration(mapsRoute, hereRoute->GetTravelTime());
+
+                       /* travel mode */
+                       maps_route_transport_mode_e eTransportMode;
+                       eTransportMode = HereUtils::Convert(hereRoute->GetTravelMode());
+                       maps_route_set_transport_mode(mapsRoute, eTransportMode);
+
+                       /* path */
+                       GeoCoordinateList herePathList = hereRoute->GetPath();
+                       maps_item_list_h mapsPathList;
+                       maps_coordinates_h mapsPath;
+
+                       if (maps_item_list_create(&mapsPathList) == MAPS_ERROR_NONE)
+                       {
+                               GeoCoordinateList::iterator herePath;
+                               for (herePath = herePathList.begin(); herePath != herePathList.end(); herePath++)
+                               {
+                                       double dLat = herePath->GetLatitude();
+                                       double dLng = herePath->GetLongitude();
+
+                                       if(maps_coordinates_create(dLat, dLng, &mapsPath) == MAPS_ERROR_NONE)
+                                       {
+                                               if (herePath == herePathList.begin())
+                                                       maps_route_set_origin(mapsRoute, mapsPath);
+                                               else if (herePath == herePathList.end()-1)
+                                                       maps_route_set_destination(mapsRoute, mapsPath);
+                                               else
+                                                       maps_item_list_append(mapsPathList, mapsPath, maps_coordinates_clone);
+
+                                               maps_coordinates_destroy(mapsPath);
+                                       }
+                               }
+
+                               if (maps_item_list_items(mapsPathList))
+                               {
+                                       maps_route_set_path(mapsRoute, mapsPathList);
+                                       maps_item_list_remove_all(mapsPathList, maps_coordinates_destroy);
+                               }
+                               maps_item_list_destroy(mapsPathList);
+                       }
+
+                       /* bounding box */
+                       maps_area_h hMapsArea = NULL;
+                       HereUtils::Convert(hereRoute->GetBounds(), hMapsArea);
+                       if (hMapsArea)
+                       {
+                               maps_route_set_bounding_box(mapsRoute, hMapsArea);
+                               maps_area_destroy(hMapsArea);
+                       }
+
+                       /* segments */
+                       ProcessSegments(mapsRoute, hereRoute->GetRouteSegmentList());
+               }
+
+               if (m_bCanceled)
+               {
+                       maps_route_destroy(mapsRoute);
+                       break;
+               }
+               else
+               {
+                       if (((maps_service_search_route_cb)m_pCbFunc)(error, m_nReqId,
+                               nReplyIdx++, nReplyNum, mapsRoute, m_pUserData) == FALSE)
+                       {
+                               delete this;
+                               return;
+                       }
+                       //maps_route_destroy(mapsRoute);
+               }
+       }
+
+       if(nReplyIdx >= nReplyNum)
+               delete this;
+}
+
+
+maps_error_e HereRoute::ProcessSegments(maps_route_h mapsRoute, const RouteSegmentList& hereSegmList)
+{
+       maps_item_list_h mapsSegmList;
+       maps_route_segment_h mapsSegm;
+       maps_error_e error;
+
+       if (hereSegmList.empty()) return MAPS_ERROR_NOT_FOUND;
+
+       if ((error = (maps_error_e)maps_item_list_create(&mapsSegmList)) != MAPS_ERROR_NONE)
+               return error;
+
+       RouteSegmentList::const_iterator hereSegm;
+       for (hereSegm = hereSegmList.begin() ; hereSegm != hereSegmList.end() ; hereSegm++)
+       {
+               if (maps_route_segment_create(&mapsSegm) != MAPS_ERROR_NONE) continue;
+
+               /* distance */
+               maps_route_segment_set_distance(mapsSegm, hereSegm->GetDistance());
+
+               /* tranvel time */
+               maps_route_segment_set_duration(mapsSegm, hereSegm->GetTravelTime());
+
+               /* origin, destination */
+               GeoCoordinateList herePathList = hereSegm->GetPath();
+               int here_path_list_size = herePathList.size();
+
+               if (here_path_list_size > 0)
+               {
+                       GeoCoordinates hereOrig = herePathList.at(0);
+                       GeoCoordinates hereDest = herePathList.at(here_path_list_size-1);
+
+                       maps_coordinates_h mapsOrig, mapsDest;
+                       maps_coordinates_create(hereOrig.GetLatitude(),
+                                               hereOrig.GetLongitude(), &mapsOrig);
+                       maps_coordinates_create(hereDest.GetLatitude(),
+                                               hereDest.GetLongitude(), &mapsDest);
+                       maps_route_segment_set_origin(mapsSegm, mapsOrig);
+                       maps_route_segment_set_destination(mapsSegm, mapsDest);
+                       maps_coordinates_destroy(mapsOrig);
+                       maps_coordinates_destroy(mapsDest);
+               }
+
+               /* maneuver */
+               ProcessManeuver(mapsSegm, hereSegm->GetManeuverList());
+
+               maps_item_list_append(mapsSegmList, mapsSegm, maps_route_segment_clone);
+               maps_route_segment_destroy(mapsSegm);
+       }
+
+       if (maps_item_list_items(mapsSegmList))
+       {
+               maps_route_set_segments(mapsRoute, mapsSegmList);
+               maps_item_list_remove_all(mapsSegmList, maps_route_segment_destroy);
+       }
+       maps_item_list_destroy(mapsSegmList);
+
+       return MAPS_ERROR_NONE;
+}
+
+maps_error_e HereRoute::ProcessManeuver(maps_route_segment_h mapsSegm, const ManeuverList& hereManeList)
+{
+       maps_item_list_h mapsManeList;
+       maps_route_maneuver_h mapsManeuver;
+       maps_coordinates_h mapsCoord;
+       maps_error_e error;
+
+       if (hereManeList.empty()) return MAPS_ERROR_NOT_FOUND;
+
+       if ((error = (maps_error_e)maps_item_list_create(&mapsManeList)) != MAPS_ERROR_NONE)
+               return error;
+
+       ManeuverList::const_iterator hereMane;
+       for (hereMane = hereManeList.begin() ; hereMane != hereManeList.end() ; hereMane++)
+       {
+               if (maps_route_maneuver_create(&mapsManeuver) != MAPS_ERROR_NONE) continue;
+
+               /* position */
+               if (maps_coordinates_create(hereMane->GetPosition().GetLatitude(),
+                       hereMane->GetPosition().GetLongitude(), &mapsCoord) == MAPS_ERROR_NONE)
+               {
+                       maps_route_maneuver_set_position(mapsManeuver, mapsCoord);
+                       maps_coordinates_destroy(mapsCoord);
+               }
+
+               /* instruction */
+               if (!hereMane->GetInstructionText().empty())
+                       maps_route_maneuver_set_instruction_text(mapsManeuver,
+                               (char*)hereMane->GetInstructionText().c_str());
+
+               /* length */
+               maps_route_maneuver_set_distance_to_next_instruction(mapsManeuver,
+                       hereMane->GetDistanceToNextInstruction());
+
+               /* travel time */
+               maps_route_maneuver_set_time_to_next_instruction(mapsManeuver,
+                       hereMane->GetTimeToNextInstruction());
+
+               /* direction -> turn type */
+               maps_route_maneuver_set_turn_type(mapsManeuver,
+                       HereUtils::Convert(hereMane->GetDirection()));
+
+               maps_item_list_append(mapsManeList, mapsManeuver, maps_route_maneuver_clone);
+               maps_route_maneuver_destroy(mapsManeuver);
+       }
+
+       if (maps_item_list_items(mapsManeList))
+       {
+               maps_route_segment_set_maneuvers(mapsSegm, mapsManeList);
+               maps_item_list_remove_all(mapsManeList, maps_route_maneuver_destroy);
+       }
+       maps_item_list_destroy(mapsManeList);
+
+       return MAPS_ERROR_NONE;
+}
+
+HERE_PLUGIN_END_NAMESPACE
+
diff --git a/src/here/here_route.h b/src/here/here_route.h
new file mode 100755 (executable)
index 0000000..c1ecb96
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LOCATION_HERE_ROUTE_H_
+#define _LOCATION_HERE_ROUTE_H_
+
+//plug-in header
+#include "here_manager.h"
+
+//maps-service header
+#include <maps_route_plugin.h>
+#include <maps_route_segment_plugin.h>
+#include <maps_route_maneuver_plugin.h>
+
+//map engine header
+#include <routes/GeoRouteQuery.h>
+#include <routes/GeoRouteQueryListener.h>
+#include <routes/GeoRouteReply.h>
+
+HERE_PLUGIN_BEGIN_NAMESPACE
+
+using namespace HERE_MAPS_NAMESPACE_PREFIX;
+
+class HereRoute
+: public HereBase
+, public GeoRouteQueryListener
+{
+public:
+       /**
+        *This is the default constructor for Route.
+        */
+
+       HereRoute(void *pCbFunc, void *pUserData, int nReqId);
+
+       /**
+        *This is the default destructor for Route.
+        */
+
+       ~HereRoute();
+
+       here_error_e PrepareQuery();
+       here_error_e PrepareWaypoint(maps_coordinates_h hOrigin, maps_coordinates_h hDestination);
+       here_error_e PrepareWaypoint(const maps_coordinates_h* hWaypointList, int nWaypointNum);
+       here_error_e PreparePreference(maps_preference_h hPref);
+
+       here_error_e StartRoute(void);
+
+       virtual void OnRouteReply(const GeoRouteReply& Reply);
+
+private:
+       maps_error_e ProcessSegments(maps_route_h mapsRoute, const RouteSegmentList& hereSegmList);
+       maps_error_e ProcessManeuver(maps_route_segment_h mapsSegm, const ManeuverList& hereManeList);
+
+       GeoRouteQuery* m_pQuery;
+};
+
+HERE_PLUGIN_END_NAMESPACE
+
+#endif //_LOCATION_HERE_ROUTE_H_
diff --git a/src/here/here_types.h b/src/here/here_types.h
new file mode 100755 (executable)
index 0000000..32899ad
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LOCATION_HERE_TYPES_H_
+#define _LOCATION_HERE_TYPES_H_
+
+#include <glib.h>
+
+typedef enum {
+    HERE_ERROR_NONE = 0,                /**< Successful */
+    HERE_ERROR_PERMISSION_DENIED,       /**< Permission Denied */
+    HERE_ERROR_OUT_OF_MEMORY,           /**< Out of memory */
+    HERE_ERROR_INVALID_PARAMETER,       /**< Invalid parameter */
+    HERE_ERROR_NOT_SUPPORTED,           /**< Not supported */
+    HERE_ERROR_CONNECTION_TIME_OUT,     /**< Timeout error, no answer */
+    HERE_ERROR_NETWORK_UNREACHABLE,     /**< Network unavailable */
+    HERE_ERROR_INVALID_OPERATION,       /**< Opeartion is not valid */
+    HERE_ERROR_KEY_NOT_AVAILABLE,       /**< Invalid key */
+    HERE_ERROR_RESOURCE_BUSY,           /**< Resource busy */
+    HERE_ERROR_CANCELED,                /**< Service canceled */
+    HERE_ERROR_UNKNOWN,                 /**< Unknown error */
+    HERE_ERROR_SERVICE_NOT_AVAILABLE,   /**< Service unavailabe*/
+    HERE_ERROR_NOT_FOUND,               /**< Result not found */
+} here_error_e;
+
+#endif //_LOCATION_HERE_TYPES_H_
diff --git a/src/here/here_utils.cpp b/src/here/here_utils.cpp
new file mode 100755 (executable)
index 0000000..9cc2c47
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "here_utils.h"
+
+
+static const double LATITUDE_RANGE = 85.05113;
+static const double LONGITUDE_RANGE = 180.0;
+
+
+extern "C"
+{
+int ConvertToMapsError(int nErr)
+{
+       switch (nErr)
+       {
+               case HERE_ERROR_NONE:                  return MAPS_ERROR_NONE;
+               case HERE_ERROR_PERMISSION_DENIED:     return MAPS_ERROR_PERMISSION_DENIED;
+               case HERE_ERROR_OUT_OF_MEMORY:         return MAPS_ERROR_OUT_OF_MEMORY;
+               case HERE_ERROR_INVALID_PARAMETER:     return MAPS_ERROR_INVALID_PARAMETER;
+               case HERE_ERROR_NOT_SUPPORTED:         return MAPS_ERROR_NOT_SUPPORTED;
+               case HERE_ERROR_CONNECTION_TIME_OUT:   return MAPS_ERROR_CONNECTION_TIME_OUT;
+               case HERE_ERROR_NETWORK_UNREACHABLE:   return MAPS_ERROR_NETWORK_UNREACHABLE;
+               case HERE_ERROR_INVALID_OPERATION:     return MAPS_ERROR_INVALID_OPERATION;
+               case HERE_ERROR_KEY_NOT_AVAILABLE:     return MAPS_ERROR_KEY_NOT_AVAILABLE;
+               case HERE_ERROR_RESOURCE_BUSY:         return MAPS_ERROR_RESOURCE_BUSY;
+               case HERE_ERROR_CANCELED:              return MAPS_ERROR_CANCELED;
+               case HERE_ERROR_UNKNOWN:               return MAPS_ERROR_UNKNOWN;
+               case HERE_ERROR_SERVICE_NOT_AVAILABLE: return MAPS_ERROR_SERVICE_NOT_AVAILABLE;
+               case HERE_ERROR_NOT_FOUND:             return MAPS_ERROR_NOT_FOUND;
+       }
+       return MAPS_ERROR_UNKNOWN;
+}
+
+int ConvertToHereError(int nErr)
+{
+       switch (nErr)
+       {
+               case MAPS_ERROR_NONE:                  return HERE_ERROR_NONE;
+               case MAPS_ERROR_PERMISSION_DENIED:     return HERE_ERROR_PERMISSION_DENIED;
+               case MAPS_ERROR_OUT_OF_MEMORY:         return HERE_ERROR_OUT_OF_MEMORY;
+               case MAPS_ERROR_INVALID_PARAMETER:     return HERE_ERROR_INVALID_PARAMETER;
+               case MAPS_ERROR_NOT_SUPPORTED:         return HERE_ERROR_NOT_SUPPORTED;
+               case MAPS_ERROR_CONNECTION_TIME_OUT:   return HERE_ERROR_CONNECTION_TIME_OUT;
+               case MAPS_ERROR_NETWORK_UNREACHABLE:   return HERE_ERROR_NETWORK_UNREACHABLE;
+               case MAPS_ERROR_INVALID_OPERATION:     return HERE_ERROR_INVALID_OPERATION;
+               case MAPS_ERROR_KEY_NOT_AVAILABLE:     return HERE_ERROR_KEY_NOT_AVAILABLE;
+               case MAPS_ERROR_RESOURCE_BUSY:         return HERE_ERROR_RESOURCE_BUSY;
+               case MAPS_ERROR_CANCELED:              return HERE_ERROR_CANCELED;
+               case MAPS_ERROR_UNKNOWN:               return HERE_ERROR_UNKNOWN;
+               case MAPS_ERROR_SERVICE_NOT_AVAILABLE: return HERE_ERROR_SERVICE_NOT_AVAILABLE;
+               case MAPS_ERROR_NOT_FOUND:             return HERE_ERROR_NOT_FOUND;
+       }
+       return HERE_ERROR_UNKNOWN;
+}
+}
+
+
+HERE_PLUGIN_BEGIN_NAMESPACE
+
+HereUtils::HereUtils()
+{
+}
+
+HereUtils::~HereUtils()
+{
+}
+
+GeoRouteQuery::TravelMode HereUtils::Convert(maps_route_transport_mode_e nVal)
+{
+       switch (nVal)
+       {
+               case MAPS_ROUTE_TRANSPORT_MODE_CAR:           return GeoRouteQuery::TM_CarTravel;
+               case MAPS_ROUTE_TRANSPORT_MODE_PEDESTRIAN:    return GeoRouteQuery::TM_PedestrianTravel;
+               case MAPS_ROUTE_TRANSPORT_MODE_PUBLICTRANSIT: return GeoRouteQuery::TM_PublicTransitTravel;
+               default: break;
+       }
+       return GeoRouteQuery::TM_CarTravel;
+}
+
+maps_route_transport_mode_e HereUtils::Convert(GeoRouteQuery::TravelMode nVal)
+{
+       switch (nVal)
+       {
+               case GeoRouteQuery::TM_CarTravel:           return MAPS_ROUTE_TRANSPORT_MODE_CAR;
+               case GeoRouteQuery::TM_PedestrianTravel:    return MAPS_ROUTE_TRANSPORT_MODE_PEDESTRIAN;
+               case GeoRouteQuery::TM_PublicTransitTravel: return MAPS_ROUTE_TRANSPORT_MODE_PUBLICTRANSIT;
+               default: break;
+       }
+       return MAPS_ROUTE_TRANSPORT_MODE_CAR;
+}
+
+GeoRouteQuery::FeatureType HereUtils::Convert(maps_route_feature_e nVal)
+{
+       switch (nVal)
+       {
+               case MAPS_ROUTE_FEATURE_NO:             return GeoRouteQuery::FT_NoFeature;
+               case MAPS_ROUTE_FEATURE_TOLL:           return GeoRouteQuery::FT_TollFeature;
+               case MAPS_ROUTE_FEATURE_MOTORWAY:       return GeoRouteQuery::FT_MotorwayFeature;
+               case MAPS_ROUTE_FEATURE_BOATFERRY:      return GeoRouteQuery::FT_BoatFerryFeature;
+               case MAPS_ROUTE_FEATURE_RAILFERRY:      return GeoRouteQuery::FT_RailFerryFeature;
+               case MAPS_ROUTE_FEATURE_PUBLICTTRANSIT: return GeoRouteQuery::FT_PublicTransitFeature;
+               case MAPS_ROUTE_FEATURE_TUNNEL:         return GeoRouteQuery::FT_TunnelFeature;
+               case MAPS_ROUTE_FEATURE_DIRTROAD:       return GeoRouteQuery::FT_DirtRoadFeature;
+               case MAPS_ROUTE_FEATURE_PARKS:          return GeoRouteQuery::FT_ParksFeature;
+               case MAPS_ROUTE_FEATURE_HOVLANE:        return GeoRouteQuery::FT_HOVLane;
+               case MAPS_ROUTE_FEATURE_STAIRS:         return GeoRouteQuery::FT_Stairs;
+               default: break;
+       }
+       return GeoRouteQuery::FT_NoFeature;
+}
+
+GeoRouteQuery::FeatureWeight HereUtils::Convert(maps_route_feature_weight_e nVal)
+{
+       switch (nVal)
+       {
+               case MAPS_ROUTE_FEATURE_WEIGHT_NORMAL:        return GeoRouteQuery::FW_NormalFeatureWeight;
+               case MAPS_ROUTE_FEATURE_WEIGHT_PREFER:        return GeoRouteQuery::FW_PreferFeatureWeight;
+               case MAPS_ROUTE_FEATURE_WEIGHT_AVOID:         return GeoRouteQuery::FW_AvoidFeatureWeight;
+               case MAPS_ROUTE_FEATURE_WEIGHT_SOFTEXCLUDE:   return GeoRouteQuery::FW_SoftExcludeFeatureWeight;
+               case MAPS_ROUTE_FEATURE_WEIGHT_STRICTEXCLUDE: return GeoRouteQuery::FW_StrictExcludeFeatureWeight;
+               default: break;
+       }
+       return GeoRouteQuery::FW_NormalFeatureWeight;
+}
+
+maps_route_turn_type_e HereUtils::Convert(Maneuver::InstructionDirection nVal)
+{
+       switch (nVal)
+       {
+               case Maneuver::ID_NoDirection:          return MAPS_ROUTE_TURN_TYPE_NONE;
+               case Maneuver::ID_DirectionForward:     return MAPS_ROUTE_TURN_TYPE_STRAIGHT;
+               case Maneuver::ID_DirectionBearRight:   return MAPS_ROUTE_TURN_TYPE_BEAR_RIGHT;
+               case Maneuver::ID_DirectionLightRight:  return MAPS_ROUTE_TURN_TYPE_LIGHT_RIGHT;
+               case Maneuver::ID_DirectionRight:       return MAPS_ROUTE_TURN_TYPE_RIGHT;
+               case Maneuver::ID_DirectionHardRight:   return MAPS_ROUTE_TURN_TYPE_HARD_RIGHT;
+               case Maneuver::ID_DirectionUTurnRight:  return MAPS_ROUTE_TURN_TYPE_UTURN_RIGHT;
+               case Maneuver::ID_DirectionUTurnLeft:   return MAPS_ROUTE_TURN_TYPE_UTURN_LEFT;
+               case Maneuver::ID_DirectionHardLeft:    return MAPS_ROUTE_TURN_TYPE_HARD_LEFT;
+               case Maneuver::ID_DirectionLeft:        return MAPS_ROUTE_TURN_TYPE_LEFT;
+               case Maneuver::ID_DirectionLightLeft:   return MAPS_ROUTE_TURN_TYPE_LIGHT_LEFT;
+               case Maneuver::ID_DirectionBearLeft:    return MAPS_ROUTE_TURN_TYPE_BEAR_LEFT;
+               default: break;
+       }
+       return MAPS_ROUTE_TURN_TYPE_NONE;
+}
+
+Maneuver::InstructionDirection HereUtils::Convert(maps_route_turn_type_e nVal)
+{
+       switch (nVal)
+       {
+               case MAPS_ROUTE_TURN_TYPE_NONE:         return Maneuver::ID_NoDirection;
+               case MAPS_ROUTE_TURN_TYPE_STRAIGHT:     return Maneuver::ID_DirectionForward;
+               case MAPS_ROUTE_TURN_TYPE_BEAR_RIGHT:   return Maneuver::ID_DirectionBearRight;
+               case MAPS_ROUTE_TURN_TYPE_LIGHT_RIGHT:  return Maneuver::ID_DirectionLightRight;
+               case MAPS_ROUTE_TURN_TYPE_RIGHT:        return Maneuver::ID_DirectionRight;
+               case MAPS_ROUTE_TURN_TYPE_HARD_RIGHT:   return Maneuver::ID_DirectionHardRight;
+               case MAPS_ROUTE_TURN_TYPE_UTURN_RIGHT:  return Maneuver::ID_DirectionUTurnRight;
+               case MAPS_ROUTE_TURN_TYPE_UTURN_LEFT:   return Maneuver::ID_DirectionUTurnLeft;
+               case MAPS_ROUTE_TURN_TYPE_HARD_LEFT:    return Maneuver::ID_DirectionHardLeft;
+               case MAPS_ROUTE_TURN_TYPE_LEFT:         return Maneuver::ID_DirectionLeft;
+               case MAPS_ROUTE_TURN_TYPE_LIGHT_LEFT:   return Maneuver::ID_DirectionLightLeft;
+               case MAPS_ROUTE_TURN_TYPE_BEAR_LEFT:    return Maneuver::ID_DirectionBearLeft;
+               default: break;
+       }
+       return Maneuver::ID_NoDirection;
+}
+
+GeoBoundingBox& HereUtils::Convert(maps_area_h hArea, GeoBoundingBox& Box)
+{
+       maps_area_s* area_s = (maps_area_s*)hArea;
+
+       if (!area_s || area_s->type != MAPS_AREA_RECTANGLE) return Box;
+
+       GeoCoordinates hereCoordLT(area_s->rect.top_left.latitude, area_s->rect.top_left.longitude);
+       GeoCoordinates hereCoordRB(area_s->rect.bottom_right.latitude, area_s->rect.bottom_right.longitude);
+
+       Box.SetTopLeft(hereCoordLT);
+       Box.SetBottomRight(hereCoordRB);
+
+       return Box;
+}
+
+maps_area_h& HereUtils::Convert(GeoBoundingBox Box, maps_area_h& hArea)
+{
+       maps_coordinates_h mapsCoordLT, mapsCoordRB;
+       GeoCoordinates hereCoordLT, hereCoordRB;
+
+       hereCoordLT = Box.GetTopLeft();
+       hereCoordRB = Box.GetBottomRight();
+
+       maps_coordinates_create(hereCoordLT.GetLatitude(), hereCoordLT.GetLongitude(), &mapsCoordLT);
+       maps_coordinates_create(hereCoordRB.GetLatitude(), hereCoordRB.GetLongitude(), &mapsCoordRB);
+
+       maps_area_create_rectangle(mapsCoordLT, mapsCoordRB, &hArea);
+
+       maps_coordinates_destroy(mapsCoordLT);
+       maps_coordinates_destroy(mapsCoordRB);
+
+       return hArea;
+}
+
+void HereUtils::Convert(String strUtf8, WString& strUtf16)
+{
+       strUtf16.assign(strUtf8.begin(), strUtf8.end());
+}
+
+void HereUtils::Convert(WString strUtf16, String& strUtf8)
+{
+       strUtf8.assign(strUtf16.begin(), strUtf16.end());
+}
+
+GeoBoundingBox& HereUtils::Convert(const char *src, GeoBoundingBox &box)
+{
+       int i = 0;
+       char *token, *next;
+       double coord[4] = { 0.0, };
+
+       token = strtok_r((char*)src, ",;", &next);
+       while (token && i < 4)
+       {
+               coord[i++] = atof(token);
+               token = strtok_r(NULL, ",;", &next);
+       }
+       box.SetTopLeft(GeoCoordinates(coord[0], coord[1]));
+       box.SetBottomRight(GeoCoordinates(coord[2], coord[3]));
+       return box;
+}
+
+bool HereUtils::IsValid(GeoCoordinates geoCoord)
+{
+       return IsValidCoord(geoCoord.GetLatitude(), geoCoord.GetLongitude());
+}
+
+bool HereUtils::IsValid(maps_coordinates_s geoCoord)
+{
+       return IsValidCoord(geoCoord.latitude, geoCoord.longitude);
+}
+
+bool HereUtils::IsValidCoord(double dLat, double dLng)
+{
+       return ((dLat <= LATITUDE_RANGE && dLat >= -LATITUDE_RANGE) &&
+               (dLng <= LONGITUDE_RANGE && dLng >= -LONGITUDE_RANGE));
+}
+
+bool HereUtils::IsValid(maps_area_s hArea)
+{
+       if (hArea.type == MAPS_AREA_RECTANGLE)
+       {
+               return (HereUtils::IsValid(hArea.rect.top_left) &&
+                       HereUtils::IsValid(hArea.rect.bottom_right));
+       }
+       else if(hArea.type == MAPS_AREA_CIRCLE)
+       {
+               return HereUtils::IsValid(hArea.circle.center);
+       }
+       else
+               return false;
+}
+
+
+HERE_PLUGIN_END_NAMESPACE
diff --git a/src/here/here_utils.h b/src/here/here_utils.h
new file mode 100755 (executable)
index 0000000..bcd1abf
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LOCATION_HERE_UTILS_H_
+#define _LOCATION_HERE_UTILS_H_
+
+//common header
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#include <math.h>
+#include <vector>
+
+//maps-service header
+#include <maps_area.h>
+#include <maps_preference.h>
+#include <maps_route_maneuver.h>
+#include <maps_service.h>
+
+//plug-in header
+#include "here_types.h"
+
+//map engine header
+#include <geocoder/GeoCoderQuery.h>
+#include <finder/DiscoveryQuery.h>
+#include <routes/GeoRouteQuery.h>
+#include <routes/Maneuver.h>
+#include <common/GeoCoordinates.h>
+
+#define HERE_PLUGIN_BEGIN_NAMESPACE  namespace Here { namespace PlugIn {
+#define HERE_PLUGIN_END_NAMESPACE    }}
+#define HERE_PLUGIN_NAMESPACE_PREFIX Here::PlugIn
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "HERE_PLUGIN"
+
+/*
+* Internal Macros
+*/
+#define MAPS_LOGD(fmt,args...)  LOGD(fmt, ##args)
+#define MAPS_LOGW(fmt,args...)  LOGW(fmt, ##args)
+#define MAPS_LOGI(fmt,args...)  LOGI(fmt, ##args)
+#define MAPS_LOGE(fmt,args...)  LOGE(fmt, ##args)
+#define MAPS_SECLOG(fmt,args...)  SECURE_LOGD(fmt, ##args)
+
+#define MAPS_CHECK_CONDITION(condition, error, msg)    \
+       do { \
+               if (condition) { \
+               } else { \
+                       MAPS_LOGE("%s(0x%08x)", msg, error); \
+                       return error; \
+               } \
+       } while (0)
+
+#define MAPS_NULL_ARG_CHECK_RETURN_FALSE(arg)\
+       do { \
+               if(arg != NULL) { \
+               } else  { \
+                       MAPS_LOGE("MAPS_ERROR_INVALID_PARAMETER");  \
+                       return false; };        \
+       } while (0)
+
+#define MAPS_NULL_ARG_CHECK(arg)       \
+       MAPS_CHECK_CONDITION(arg != NULL,MAPS_ERROR_INVALID_PARAMETER,"MAPS_ERROR_INVALID_PARAMETER")
+
+#define MAPS_PRINT_ERROR_CODE_RETURN(code) \
+       do{ \
+               MAPS_LOGE("%s(0x%08x)", #code, code); \
+               return code;    \
+       } while (0)
+
+#ifndef TIZEN_MIGRATION
+typedef std::string String;
+typedef std::string Uri;
+typedef std::wstring WString;
+#endif
+
+#define maps_item_list_items(item_list) g_list_length((GList*)(*(unsigned long*)item_list)  )
+
+extern "C"
+{
+       int ConvertToMapsError(int nRet);
+       int ConvertToHereError(int nRet);
+}
+
+HERE_PLUGIN_BEGIN_NAMESPACE
+
+using namespace HERE_MAPS_NAMESPACE_PREFIX;
+
+class HereUtils
+{
+public:
+       /**
+        *This is the default constructor for Geocoder.
+        */
+
+       HereUtils();
+
+       /**
+        *This is the default destructor for Geocoder.
+        */
+
+       ~HereUtils();
+
+       static GeoRouteQuery::TravelMode Convert(maps_route_transport_mode_e nVal);
+       static maps_route_transport_mode_e Convert(GeoRouteQuery::TravelMode nVal);
+       static GeoRouteQuery::FeatureType Convert(maps_route_feature_e nVal);
+       static GeoRouteQuery::FeatureWeight Convert(maps_route_feature_weight_e nVal);
+       static Maneuver::InstructionDirection Convert(maps_route_turn_type_e nVal);
+       static maps_route_turn_type_e Convert(Maneuver::InstructionDirection nVal);
+       static GeoBoundingBox& Convert(maps_area_h hArea, GeoBoundingBox& Box);
+       static maps_area_h& Convert(GeoBoundingBox Box, maps_area_h& hArea);
+       static void Convert(String strUtf8, WString& strUtf16);
+       static void Convert(WString strUtf16, String& strUtf8);
+       static GeoBoundingBox& Convert(const char *src, GeoBoundingBox &box);
+
+       static bool IsValid(GeoCoordinates geoCoord);
+       static bool IsValid(maps_coordinates_s geoCoord);
+       static bool IsValidCoord(double dLat, double dLng);
+       static bool IsValid(maps_area_s hArea);
+
+private:
+};
+
+HERE_PLUGIN_END_NAMESPACE
+
+#endif //_LOCATION_HERE_UTILS_H_
diff --git a/src/here_plugin.cpp b/src/here_plugin.cpp
new file mode 100755 (executable)
index 0000000..43e3c77
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <maps_plugin.h>
+#include "here_api.h"
+#include "here_types.h"
+#include "here_utils.h"
+
+extern "C"
+{
+
+EXPORT_API int maps_plugin_init(maps_plugin_h *plugin)
+{
+       if (!plugin)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       int ret = HerePluginInit(plugin);
+
+       MAPS_LOGD("here_error_e = %d", ret);
+
+       return ConvertToMapsError(ret);
+}
+
+EXPORT_API int maps_plugin_shutdown(maps_plugin_h plugin)
+{
+       if (!plugin)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       int ret = HerePluginShutdown(plugin);
+
+       MAPS_LOGD("here_error_e = %d", ret);
+
+       return ConvertToMapsError(ret);
+}
+
+EXPORT_API int maps_plugin_get_info(maps_plugin_info_h* info)
+{
+       if (!info)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       maps_plugin_info_create(info);
+       maps_plugin_info_set_provider_name(*info, "HERE");
+
+       return MAPS_ERROR_NONE;
+}
+
+EXPORT_API int maps_plugin_set_provider_key(const char* provider_key)
+{
+       if (!provider_key)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       int ret = HerePluginSetProviderKey(provider_key);
+
+       MAPS_LOGD("here_error_e = %d", ret);
+
+       return ConvertToMapsError(ret);
+}
+
+EXPORT_API int maps_plugin_get_provider_key(char** provider_key)
+{
+       if (!provider_key)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       int ret = HerePluginGetProviderKey(provider_key);
+
+       MAPS_LOGD("here_error_e = %d", ret);
+
+       return ConvertToMapsError(ret);
+}
+
+EXPORT_API int maps_plugin_set_preference(maps_preference_h preference)
+{
+       if (!preference)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       int ret = HerePluginSetPreference(preference);
+
+       MAPS_LOGD("here_error_e = %d", ret);
+
+       return ConvertToMapsError(ret);
+}
+
+EXPORT_API int maps_plugin_get_preference(maps_preference_h* preference)
+{
+       if (!preference)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       int ret = HerePluginGetPreference(preference);
+
+       MAPS_LOGD("here_error_e = %d", ret);
+
+       return ConvertToMapsError(ret);
+}
+
+EXPORT_API int maps_plugin_is_service_supported(maps_service_e service, bool *supported)
+{
+       if (!supported)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       switch(service)
+       {
+               case MAPS_SERVICE_GEOCODE:
+               case MAPS_SERVICE_GEOCODE_INSIDE_AREA:
+               case MAPS_SERVICE_GEOCODE_BY_STRUCTURED_ADDRESS:
+               case MAPS_SERVICE_REVERSE_GEOCODE:
+               case MAPS_SERVICE_SEARCH_PLACE:
+               case MAPS_SERVICE_SEARCH_PLACE_BY_AREA:
+               case MAPS_SERVICE_SEARCH_PLACE_BY_ADDRESS:
+               case MAPS_SERVICE_SEARCH_ROUTE:
+               case MAPS_SERVICE_SEARCH_ROUTE_WAYPOINTS:
+               case MAPS_SERVICE_CANCEL_REQUEST:
+                       *supported = TRUE;
+                       return MAPS_ERROR_NONE;
+               default:
+                       *supported = FALSE;
+                       return MAPS_ERROR_NOT_SUPPORTED;
+       }
+}
+
+EXPORT_API int maps_plugin_is_data_supported(maps_service_data_e service, bool *supported)
+{
+       if (!supported)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       switch(service)
+       {
+               case MAPS_PLACE_ADDRESS:
+               case MAPS_PLACE_RATING:
+               case MAPS_PLACE_CATEGORIES:
+               case MAPS_PLACE_ATTRIBUTES:
+               case MAPS_PLACE_CONTACTS:
+               case MAPS_PLACE_EDITORIALS:
+               case MAPS_PLACE_REVIEWS:
+               case MAPS_PLACE_IMAGE:
+               case MAPS_PLACE_SUPPLIER:
+               case MAPS_PLACE_RELATED:
+               case MAPS_ROUTE_PATH:
+               case MAPS_ROUTE_SEGMENTS_PATH:
+               case MAPS_ROUTE_SEGMENTS_MANEUVERS:
+                       *supported = TRUE;
+                       return MAPS_ERROR_NONE;
+               default:
+                       *supported = FALSE;
+                       return MAPS_ERROR_NOT_SUPPORTED;
+       }
+}
+
+EXPORT_API int maps_plugin_geocode(const char* address, const maps_preference_h preference,
+       maps_service_geocode_cb callback, void *user_data, int* request_id)
+{
+       if (!address || !callback || !request_id)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       int ret = HerePluginGeocode(address, preference, callback, user_data, request_id);
+
+       MAPS_LOGD("here_error_e = %d", ret);
+
+       return ConvertToMapsError(ret);
+}
+
+EXPORT_API int maps_plugin_geocode_inside_area(const char* address, const maps_area_h bounds,
+       const maps_preference_h preference, maps_service_geocode_cb callback,
+       void* user_data, int* request_id)
+{
+       if (!bounds || !address || !callback || !request_id)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       int ret = HerePluginGeocodeInsideArea(address, bounds, preference, callback, user_data, request_id);
+
+       MAPS_LOGD("here_error_e = %d", ret);
+
+       return ConvertToMapsError(ret);
+}
+
+EXPORT_API int maps_plugin_geocode_by_structured_address(const maps_address_h address,
+       const maps_preference_h preference, maps_service_geocode_cb callback,
+       void *user_data, int* request_id)
+{
+       if (!address || !callback || !request_id)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       int ret = HerePluginGeocodeByStructuredAddress(address, preference, callback, user_data, request_id);
+
+       MAPS_LOGD("here_error_e = %d", ret);
+
+       return ConvertToMapsError(ret);
+}
+
+EXPORT_API int maps_plugin_reverse_geocode(double latitude, double longitude,
+       const maps_preference_h preference, maps_service_reverse_geocode_cb callback,
+       void *user_data, int* request_id)
+{
+       if (!callback || !request_id)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       int ret = HerePluginReverseGeocode(latitude, longitude, preference, callback, user_data, request_id);
+
+       MAPS_LOGD("here_error_e = %d", ret);
+
+       return ConvertToMapsError(ret);
+}
+
+EXPORT_API int maps_plugin_search_place(const maps_coordinates_h position, int distance,
+       const maps_place_filter_h filter, maps_preference_h preference, maps_service_search_place_cb callback,
+       void* user_data, int* request_id)
+{
+       if (!position || !filter || !callback || !request_id)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       int ret = HerePluginSearchPlace(position, distance, preference, filter, callback, user_data, request_id);
+
+       MAPS_LOGD("here_error_e = %d", ret);
+
+       return ConvertToMapsError(ret);
+}
+
+EXPORT_API int maps_plugin_search_place_by_area(const maps_area_h boundary,
+       const maps_place_filter_h filter, maps_preference_h preference, maps_service_search_place_cb callback,
+       void* user_data, int* request_id)
+{
+       if (!boundary || !filter || !callback || !request_id)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       int ret = HerePluginSearchPlaceByArea(boundary, preference, filter, callback, user_data, request_id);
+
+       MAPS_LOGD("here_error_e = %d", ret);
+
+       return ConvertToMapsError(ret);
+}
+
+EXPORT_API int maps_plugin_search_place_by_address(const char* address, const maps_area_h boundary,
+       const maps_place_filter_h filter, maps_preference_h preference, maps_service_search_place_cb callback,
+       void* user_data, int* request_id)
+{
+       if (!address || !boundary || !filter || !callback || !request_id)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       int ret = HerePluginSearchPlaceByAddress(address, boundary, preference, filter, callback, user_data, request_id);
+
+       MAPS_LOGD("here_error_e = %d", ret);
+
+       return ConvertToMapsError(ret);
+}
+
+EXPORT_API int maps_plugin_search_route(const maps_coordinates_h origin, const maps_coordinates_h destination,
+       maps_preference_h preference, maps_service_search_route_cb callback,
+       void* user_data, int* request_id)
+{
+       if (!origin || !destination || !callback || !request_id)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       int ret = HerePluginSearchRoute(origin, destination, preference, callback, user_data, request_id);
+
+       MAPS_LOGD("here_error_e = %d", ret);
+
+       return ConvertToMapsError(ret);
+}
+
+EXPORT_API int maps_plugin_search_route_waypoints(const maps_coordinates_h* waypoint_list, int waypoint_num,
+       maps_preference_h preference, maps_service_search_route_cb callback,
+       void* user_data, int* request_id)
+{
+       if (!waypoint_list || waypoint_num <= 0 || !callback || !request_id)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       int ret = HerePluginSearchRouteWaypoints(waypoint_list, waypoint_num, preference, callback, user_data, request_id);
+
+       MAPS_LOGD("here_error_e = %d", ret);
+
+       return ConvertToMapsError(ret);
+}
+
+EXPORT_API int maps_plugin_cancel_request(int request_id)
+{
+       if (request_id < 0)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       int ret = HerePluginCancelRequest(request_id);
+
+       MAPS_LOGD("here_error_e = %d", ret);
+
+       return ConvertToMapsError(ret);
+}
+
+} // end of extern "C"
+