diff --git a/NOTICE b/NOTICE
index abbb549bdc030ecc7b3265d2132ae41f496698db..529196b6b86fb4333aaddb34d5fa5e08347e9741 100644
--- a/NOTICE
+++ b/NOTICE
@@ -279,7 +279,7 @@ The following software have components provided under the terms of this license:
 - Spring JMS (from http://www.springframework.org, https://github.com/SpringSource/spring-framework, https://github.com/spring-projects/spring-framework, https://repo1.maven.org/maven2/org/springframework/spring-jms)
 - Spring Messaging (from https://github.com/spring-projects/spring-framework)
 - Spring Object/XML Marshalling (from https://github.com/spring-projects/spring-framework)
-- Spring Plugin - Metadata Extension (from https://repo1.maven.org/maven2/org/springframework/plugin/spring-plugin-metadata)
+- Spring Plugin - Metadata Extension (from https://github.com/spring-projects/spring-plugin/spring-plugin-metadata, https://repo1.maven.org/maven2/org/springframework/plugin/spring-plugin-metadata)
 - Spring Plugin Core (from https://github.com/spring-projects/spring-plugin/spring-plugin-core, https://repo1.maven.org/maven2/org/springframework/plugin/spring-plugin-core)
 - Spring Security - Core (from http://spring.io/spring-security, https://repo1.maven.org/maven2/org/springframework/security/spring-security-core, https://spring.io/projects/spring-security, https://spring.io/spring-security)
 - Spring Security - Namespace Configuration Module (from http://spring.io/spring-security, https://repo1.maven.org/maven2/org/springframework/security/spring-security-config, https://spring.io/projects/spring-security, https://spring.io/spring-security)
@@ -403,7 +403,6 @@ BSD-3-Clause
 ========================================================================
 The following software have components provided under the terms of this license:
 
-- ${project.groupId}:${project.artifactId} (from https://repo1.maven.org/maven2/org/locationtech/jts/io/jts-io-common)
 - API Common (from https://github.com/googleapis, https://github.com/googleapis/api-common-java, https://repo1.maven.org/maven2/com/google/api/api-common)
 - ASM Analysis (from http://asm.ow2.io/)
 - ASM Commons (from http://asm.ow2.io/, https://repo1.maven.org/maven2/org/ow2/asm/asm-commons)
@@ -466,7 +465,8 @@ The following software have components provided under the terms of this license:
 - jersey-core-server (from https://repo1.maven.org/maven2/org/glassfish/jersey/core/jersey-server)
 - jersey-ext-bean-validation (from https://repo1.maven.org/maven2/org/glassfish/jersey/ext/jersey-bean-validation)
 - jersey-media-json-jackson (from https://repo1.maven.org/maven2/org/glassfish/jersey/media/jersey-media-json-jackson)
-- org.locationtech.jts:jts-core (from https://repo1.maven.org/maven2/org/locationtech/jts/jts-core)
+- jts-core (from https://repo1.maven.org/maven2/org/locationtech/jts/jts-core)
+- org.locationtech.jts.io:jts-io-common (from https://repo1.maven.org/maven2/org/locationtech/jts/io/jts-io-common)
 
 ========================================================================
 Beerware
@@ -511,6 +511,7 @@ The following software have components provided under the terms of this license:
 
 - Guava: Google Core Libraries for Java (from http://code.google.com/p/guava-libraries, https://github.com/google/guava, https://repo1.maven.org/maven2/com/google/guava/guava)
 - HdrHistogram (from http://hdrhistogram.github.io/HdrHistogram/)
+- Hibernate Validator (from https://repo1.maven.org/maven2/org/hibernate/hibernate-validator, https://repo1.maven.org/maven2/org/hibernate/validator/hibernate-validator)
 - LatencyUtils (from http://latencyutils.github.io/LatencyUtils/)
 - MongoDB Java Driver (from http://mongodb.org/, http://www.mongodb.org, https://www.mongodb.com/)
 - Netty/Common (from https://repo1.maven.org/maven2/io/netty/netty-common)
@@ -582,7 +583,6 @@ EPL-1.0
 ========================================================================
 The following software have components provided under the terms of this license:
 
-- ${project.groupId}:${project.artifactId} (from https://repo1.maven.org/maven2/org/locationtech/jts/io/jts-io-common)
 - AspectJ Weaver (from http://www.aspectj.org, https://www.eclipse.org/aspectj/)
 - JUnit Jupiter (Aggregator) (from https://junit.org/junit5/)
 - JUnit Jupiter API (from http://junit.org/junit5/, https://junit.org/junit5/)
@@ -602,7 +602,8 @@ The following software have components provided under the terms of this license:
 - aopalliance-repackaged (from https://repo1.maven.org/maven2/org/glassfish/hk2/external/aopalliance-repackaged)
 - jersey-core-server (from https://repo1.maven.org/maven2/org/glassfish/jersey/core/jersey-server)
 - jersey-media-json-jackson (from https://repo1.maven.org/maven2/org/glassfish/jersey/media/jersey-media-json-jackson)
-- org.locationtech.jts:jts-core (from https://repo1.maven.org/maven2/org/locationtech/jts/jts-core)
+- jts-core (from https://repo1.maven.org/maven2/org/locationtech/jts/jts-core)
+- org.locationtech.jts.io:jts-io-common (from https://repo1.maven.org/maven2/org/locationtech/jts/io/jts-io-common)
 
 ========================================================================
 EPL-2.0
@@ -734,7 +735,6 @@ ISC
 ========================================================================
 The following software have components provided under the terms of this license:
 
-- Java Native Access Platform (from https://github.com/java-native-access/jna)
 - Spring Security - Core (from http://spring.io/spring-security, https://repo1.maven.org/maven2/org/springframework/security/spring-security-core, https://spring.io/projects/spring-security, https://spring.io/spring-security)
 
 ========================================================================
@@ -805,7 +805,6 @@ The following software have components provided under the terms of this license:
 
 - AWS Java SDK for AWS Lambda (from https://aws.amazon.com/sdkforjava)
 - Animal Sniffer Annotations (from https://repo1.maven.org/maven2/org/codehaus/mojo/animal-sniffer-annotations)
-- Apache HttpClient Cache (from http://hc.apache.org/httpcomponents-client, http://hc.apache.org/httpcomponents-client-ga)
 - Apache Log4j API (from https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-api)
 - Apache Log4j SLF4J Binding (from https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-slf4j-impl)
 - Apache Log4j to SLF4J Adapter (from https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-to-slf4j)
diff --git a/testing/integration-tests/search-test-azure/src/test/java/org/opengroup/osdu/step_definitions/querybycursor/singlecluster/RunTest.java b/testing/integration-tests/search-test-azure/src/test/java/org/opengroup/osdu/step_definitions/querybycursor/singlecluster/RunTest.java
index f80ca74843b1680fe6b4efb216172b126d7951d7..a478527b97a6244889533203b3ee972e9f30aef7 100644
--- a/testing/integration-tests/search-test-azure/src/test/java/org/opengroup/osdu/step_definitions/querybycursor/singlecluster/RunTest.java
+++ b/testing/integration-tests/search-test-azure/src/test/java/org/opengroup/osdu/step_definitions/querybycursor/singlecluster/RunTest.java
@@ -20,7 +20,7 @@ import org.junit.runner.RunWith;
 
 @RunWith(Cucumber.class)
 @CucumberOptions(
-        features = "classpath:features/querybycursor/singlecluster/QueryByCursor.feature",
+        features = "classpath:features/querybycursor/singlecluster/SingleClusterQueryByCursor.feature",
         glue = {"classpath:org.opengroup.osdu.step_definitions/querybycursor/singlecluster"},
         plugin = {"pretty", "junit:target/cucumber-reports/TEST-querybycursor-sc.xml"})
 public class RunTest {
diff --git a/testing/integration-tests/search-test-azure/src/test/resources/features/query/singlecluster/SingleClusterQuery.feature b/testing/integration-tests/search-test-azure/src/test/resources/features/query/singlecluster/SingleClusterQuery.feature
index 877d0cdc58b8aa2c91a1b44f6b8838a82f4f0205..8e2628e711a865d23271e1625c10267dd7dbad3c 100644
--- a/testing/integration-tests/search-test-azure/src/test/resources/features/query/singlecluster/SingleClusterQuery.feature
+++ b/testing/integration-tests/search-test-azure/src/test/resources/features/query/singlecluster/SingleClusterQuery.feature
@@ -39,7 +39,7 @@ Feature: Search with different queries
       #####################################Text Query test cases###########################################################################
       | "tenant1" | "tenant1:search<timestamp>:test-data--Integration:1.0.1" | "OSDU"                               | None  | None   | All             | 3     |
       | "tenant1" | "tenant1:search<timestamp>:test-data2--Integration:1.0.2" | "data.OriginalOperator:OFFICE6"      | None  | None   | All             | 1     |
-      | "tenant1" | "tenant1:search<timestamp>:test-data--Integration:1.0.1" | ""OFFICE2" \| OFFICE3"               | None  | None   | All             | 1     |
+      | "tenant1" | "tenant1:search<timestamp>:test-data--Integration:1.0.1" | ""data.OriginalOperator:OFFICE2" \| data.OriginalOperator:OFFICE3"               | None  | None   | All             | 1     |
       | "tenant1" | "tenant1:search<timestamp>:test-data2--Integration:1.0.2" | "data.Well\*:(Data Lake Cloud)"      | None  | None   | All             | 3     |
 
   Scenario Outline: Search data in a given kind with hundreds of copies
@@ -144,7 +144,7 @@ Feature: Search with different queries
       | "tenant1" | "tenant1:search<timestamp>:*:*" | ""SCHLUM OFFICE""                          | None  | None   | All             | 0     |
       | "tenant1" | "tenant1:search<timestamp>:*:*" | "data.Country:USA"                         | None  | None   | All             | 2     |
       | "tenant1" | "tenant1:search<timestamp>:*:*" | "TEXAS AND OFFICE3"                        | None  | None   | All             | 1     |
-      | "tenant1" | "tenant1:search<timestamp>:*:*" | "data.OriginalOperator:OFFICE5 OR OFFICE2" | None  | None   | All             | 2     |
+      | "tenant1" | "tenant1:search<timestamp>:*:*" | "data.OriginalOperator:OFFICE5 OR data.OriginalOperator:OFFICE2" | None  | None   | All             | 2     |
       | "tenant1" | "tenant1:search<timestamp>:*:*" | "data.OriginalOperator:STI OR HT"          | None  | None   | All             | 0     |
       | "tenant1" | "tenant1:search<timestamp>:*:*" | "_exists_:data.Basin"                      | None  | None   | All             | 4     |
       | "tenant1" | "tenant1:search<timestamp>:*:*" | "data.Well\*:"Data Lake Cloud""            | None  | None   | All             | 5     |
@@ -167,11 +167,11 @@ Feature: Search with different queries
     And I apply geographical query on field <field>
     Then I should get in response <count> records
     Examples:
-      | kind                                      | query     | field                   | points_list                                                                                                        | count |
-      | "tenant1:search<timestamp>:test-data--Integration:1.0.1" | None      | "data.Location"         | (26.12362;-112.226716)  , (26.595873;-68.457186) , (52.273184;-93.593904)                                          | 2     |
-      | "tenant1:search<timestamp>:test-data--Integration:1.0.1" | None      | "data.Location"         | (33.201112;-113.282863) , (33.456305;-98.269744) , (52.273184;-93.593904)                                          | 0     |
-      | "tenant1:search<timestamp>:test-data--Integration:1.0.1" | "OFFICE4" | "data.Location"         | (26.12362;-112.226716)  , (26.595873;-68.457186) , (52.273184;-93.593904)                                          | 1     |
-      | "tenant1:search<timestamp>:test-data--Integration:1.0.1" | None      | "data.Location"         | (14.29056;72.18936)     , (22.13762;72.18936)    , (22.13762;77.18936) , (14.29056;77.18936) , (14.29056;72.18936) | 1     |
+      | kind                                                     | query                           | field           | points_list                                                                                                        | count |
+      | "tenant1:search<timestamp>:test-data--Integration:1.0.1" | None                            | "data.Location" | (26.12362;-112.226716)  , (26.595873;-68.457186) , (52.273184;-93.593904)                                          | 2     |
+      | "tenant1:search<timestamp>:test-data--Integration:1.0.1" | None                            | "data.Location" | (33.201112;-113.282863) , (33.456305;-98.269744) , (52.273184;-93.593904)                                          | 0     |
+      | "tenant1:search<timestamp>:test-data--Integration:1.0.1" | "data.OriginalOperator:OFFICE4" | "data.Location" | (26.12362;-112.226716)  , (26.595873;-68.457186) , (52.273184;-93.593904)                                          | 1     |
+      | "tenant1:search<timestamp>:test-data--Integration:1.0.1" | None                            | "data.Location" | (14.29056;72.18936)     , (22.13762;72.18936)    , (22.13762;77.18936) , (14.29056;77.18936) , (14.29056;72.18936) | 1     |
 
   Scenario Outline: Search data across the kinds with invalid geo polygon inputs
     When I send <query> with <kind>
@@ -219,7 +219,7 @@ Feature: Search with different queries
       | "tenant1:search<timestamp>:test-data--Integration:1.0.1" | None      | false    | 3     |
       | "tenant1:search<timestamp>:test-data2--Integration:1.0.2" | None      | false    | 3     |
       | "tenant1:search<timestamp>:*:*"     | None      | false    | 6     |
-      | "tenant1:search<timestamp>:*:*"     | "OFFICE4" | true     | 1     |
+      | "tenant1:search<timestamp>:*:*"     | "data.OriginalOperator:OFFICE4" | true     | 1     |
       | "tenant1:search<timestamp>:*:*"     | None      | None     | 6     |
 
   Scenario Outline: Search data in a given kind with aggregateBy field
@@ -228,13 +228,13 @@ Feature: Search with different queries
     Then I should get <count> unique values
 
     Examples:
-      | kind                                            | query                                                          | aggregateBy                                              | count |
-      | "tenant1:search<timestamp>:test-data--Integration:1.0.1"       | None                                                           | "namespace"                                              | 1     |
-      | "tenant1:search<timestamp>:test-data--Integration:1.0.1"       | None                                                           | "type"                                                   | 1     |
-      | "tenant1:search<timestamp>:test-data--Integration:1.0.1"       | "OFFICE4"                                                      | "data.Rank"                                              | 1     |
-      | "tenant1:search<timestamp>:test-data--Integration:1.0.1"       | None                                                           | "data.Rank"                                              | 3     |
-      | "tenant1:well<timestamp>:test-data3--Integration:1.0.3" | None                                                           | "nested(data.VerticalMeasurements, VerticalMeasurement)" | 2     |
-      | "tenant1:well<timestamp>:test-data3--Integration:1.0.3" | nested(data.VerticalMeasurements, (VerticalMeasurement:(<15))) | "nested(data.VerticalMeasurements, VerticalMeasurement)" | 1     |
+      | kind                                                     | query                                                          | aggregateBy                                              | count |
+      | "tenant1:search<timestamp>:test-data--Integration:1.0.1" | None                                                           | "namespace"                                              | 1     |
+      | "tenant1:search<timestamp>:test-data--Integration:1.0.1" | None                                                           | "type"                                                   | 1     |
+      | "tenant1:search<timestamp>:test-data--Integration:1.0.1" | "data.OriginalOperator:OFFICE4"                                | "data.Rank"                                              | 1     |
+      | "tenant1:search<timestamp>:test-data--Integration:1.0.1" | None                                                           | "data.Rank"                                              | 3     |
+      | "tenant1:well<timestamp>:test-data3--Integration:1.0.3"  | None                                                           | "nested(data.VerticalMeasurements, VerticalMeasurement)" | 2     |
+      | "tenant1:well<timestamp>:test-data3--Integration:1.0.3"  | nested(data.VerticalMeasurements, (VerticalMeasurement:(<15))) | "nested(data.VerticalMeasurements, VerticalMeasurement)" | 1     |
 
   Scenario Outline: Search data in a given kind with nested queries
     When I send <query> with <kind>
diff --git a/testing/integration-tests/search-test-azure/src/test/resources/features/querybycursor.singlecluster/SingleClusterQueryByCursor.feature b/testing/integration-tests/search-test-azure/src/test/resources/features/querybycursor.singlecluster/SingleClusterQueryByCursor.feature
new file mode 100644
index 0000000000000000000000000000000000000000..e35eb652b7483e179ab9174aca0e0ae6d6e75a70
--- /dev/null
+++ b/testing/integration-tests/search-test-azure/src/test/resources/features/querybycursor.singlecluster/SingleClusterQueryByCursor.feature
@@ -0,0 +1,84 @@
+Feature: Search recursively on cursor with different queries
+  To allow a user to find his data quickly, search should offer multiple ways to search data and iterate over all the results.
+
+  Background:
+    Given the schema is created with the following kind
+      | kind                                           | schemaFile |
+      | tenant1:search<timestamp>:test-data--Integration:1.0.1    | records_1  |
+      | tenant1:search<timestamp>:test-data2--Integration:1.0.2    | records_2  |
+
+  Scenario Outline: Ingest records for the given kind
+    When I ingest records with the <recordFile> with <acl> for a given <kind>
+    Examples:
+      | kind                                          | recordFile  | acl                             |
+      | "tenant1:search<timestamp>:test-data--Integration:1.0.1" | "records_1" |  "data.default.viewers@tenant1" |
+      | "tenant1:search<timestamp>:test-data2--Integration:1.0.2"  | "records_2" | "data.default.viewers@tenant1"  |
+
+  Scenario Outline: Search recursively page by page data across the kinds
+    When I send <query> with <kind>
+    And I limit the count of returned results to <limit>
+    And I set the fields I want in response as <returned_fields>
+    And I send request to tenant <q1_tenant>
+    Then I should get in response <first_count> records along with a cursor
+    And I send request to tenant <q2_tenant>
+    Then I should get in response <final_count> records
+
+    Examples:
+      | q1_tenant | q2_tenant | kind                                | query                     | limit | returned_fields | first_count | final_count |
+      | "tenant1" | "tenant1" | "tenant1:search<timestamp>:*:*" | None                      | 4     | All             | 4           | 2           |
+      | "tenant1" | "tenant1" | "tenant1:search<timestamp>:*:*" | None                      | None  | All             | 6           | 0           |
+      | "tenant1" | "tenant1" | "tenant1:search<timestamp>:*:*" | "TX OR TEXAS OR FRANCE"   | 1     | All             | 1           | 1           |
+      | "tenant1" | "tenant1" | "tenant1:search<timestamp>:*:*" | "XdQQ6GCSNSBLTESTFAIL"    | 1     | All             | 0           | 0           |
+      | "tenant1" | "tenant1" | "tenant1:search<timestamp>:*:*" | "\"OFFICE2\" \| OFFICE3 \| OFFICE5" | 1     | All             | 1           | 1           |
+
+  Scenario Outline: Search recursively page by page data across the kinds with invalid inputs
+    When I send <query> with <kind>
+    And I limit the count of returned results to <limit>
+    And I set an invalid cursor
+    And I send request to tenant <tenant>
+    Then I should get <response_code> response with reason: <reponse_type>, message: <response_message> and errors: <errors>
+
+    Examples:
+      | tenant    | kind                                       | query | limit | response_code | reponse_type                  | response_message                                  | errors                                    |
+      | "tenant1" | "tenant1:search<timestamp>:test-data--Integration:1.0.1" | None  | None  | 400           | "Can't find the given cursor" | "The given cursor is invalid or expired"          | ""                                        |
+      | "tenant1" | "*:*:*"                                    | None  | 0     | 400           | "Bad Request"                 | "Invalid parameters were given on search request" | "Not a valid record kind format. Found: *:*:*"   |
+      | "tenant1" | "tenant1:search<timestamp>:test-data--Integration:1.0.1" | None  | -1    | 400           | "Bad Request"                 | "Invalid parameters were given on search request" | "'limit' must be equal or greater than 0" |
+
+  Scenario Outline:  Search recursively page by page data across the kinds with invalid inputs and headers
+    When I send <query> with <kind>
+    And I limit the count of returned results to <limit>
+    And I set the fields I want in response as <returned_fields>
+    And I send request to tenant <q1_tenant>
+    Then I should get in response <first_count> records along with a cursor
+    And I send request to tenant <q2_tenant>
+    Then I should get <response_code> response with reason: <reponse_type>, message: <response_message> and errors: <errors>
+
+    Examples:
+      | q1_tenant | q2_tenant | kind                                       | query | limit | returned_fields | first_count | response_code | reponse_type    | response_message                                    | errors |
+      | "tenant1" | "tenant2" | "tenant1:search<timestamp>:test-data--Integration:1.0.1" | None  | 1     | All             | 1           | 401           | "Access denied" | "The user is not authorized to perform this action" | ""     |
+
+  Scenario Outline: Search data across the kinds with bounding box inputs
+    When I send <query> with <kind>
+    And I apply geographical query on field <field>
+    And define bounding box with points (<top_left_latitude>, <top_left_longitude>) and  (<bottom_right_latitude>, <bottom_right_longitude>)
+    And I limit the count of returned results to <limit>
+    And I send request to tenant <q1_tenant>
+    Then I should get in response <first_count> records along with a cursor
+    And I send request to tenant <q2_tenant>
+    Then I should get in response <final_count> records
+
+    Examples:
+      | q1_tenant | q2_tenant | kind                                       | query  | limit | field           | top_left_latitude | top_left_longitude | bottom_right_latitude | bottom_right_longitude | first_count | final_count |
+      | "tenant1" | "tenant1" | "tenant1:search<timestamp>:test-data--Integration:1.0.1" | None   | None  | "data.Location" | 45                | -100               | 0                     | 0                      | 2           | 0           |
+      | "tenant1" | "tenant1" | "tenant1:search<timestamp>:test-data--Integration:1.0.1" | "data.OriginalOperator:OFFICE4" | 1     | "data.Location" | 45                | -110               | 0                     | 0                      | 1           | 0           |
+
+
+  Scenario Outline: Search data and sort the results with the given sort fields and order
+    When I send <query> with <kind>
+    And I want the results sorted by <sort>
+    Then I should get records in right order first record id: <first_record_id>, last record id: <last_record_id>
+    Examples:
+      | kind                                      | query       | sort                                                                         | first_record_id       | last_record_id        |
+      | "tenant1:search<timestamp>:*:*"    | None        | {"field":["data.OriginalOperator"],"order":["ASC"]}                          | "tenant1:search<timestamp>:1"   | "tenant1:search<timestamp>:2.0.0:3"   |
+      | "tenant1:search<timestamp>:*:*"    | None        | {"field":["id"],"order":["DESC"]}                                            | "tenant1:search<timestamp>:3"   | "tenant1:search<timestamp>:1"   |
+      | "tenant1:search<timestamp>:*:*"    | None        | {"field":["namespace","data.Rank"],"order":["ASC","DESC"]}                   | "tenant1:search<timestamp>:3"   | "tenant1:search<timestamp>:2.0.0:1"   |