diff --git a/tmf/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfEventTableDataProviderTest.java b/tmf/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfEventTableDataProviderTest.java
index a9f5fa4..b696676 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfEventTableDataProviderTest.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/event/TmfEventTableDataProviderTest.java
@@ -27,6 +27,7 @@
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.tracecompass.internal.provisional.tmf.core.model.events.TmfEventTableColumnDataModel;
 import org.eclipse.tracecompass.internal.provisional.tmf.core.model.events.TmfEventTableDataProvider;
+import org.eclipse.tracecompass.internal.provisional.tmf.core.model.events.TmfEventTableDataProvider.Direction;
 import org.eclipse.tracecompass.internal.provisional.tmf.core.model.events.TmfEventTableFilterModel;
 import org.eclipse.tracecompass.internal.provisional.tmf.core.model.filters.EventTableQueryFilter;
 import org.eclipse.tracecompass.internal.provisional.tmf.core.model.filters.VirtualTableQueryFilter;
@@ -36,7 +37,6 @@
 import org.eclipse.tracecompass.internal.provisional.tmf.core.model.table.TmfVirtualTableModel;
 import org.eclipse.tracecompass.internal.provisional.tmf.core.model.table.VirtualTableCell;
 import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
-import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
 import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
 import org.eclipse.tracecompass.tmf.core.model.CoreFilterProperty;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
@@ -321,8 +321,45 @@
     }
 
     /**
+     * Given a start index, count and a list of desired columns, we check model returned by
+     * the data provider. We also apply a search filter on a single column, where no event matches
+     * the search expression.
+     */
+    @Test
+    public void testDataProviderWithSearchNoMatch() {
+        Long eventTypeColumnId = fColumns.get(EVENT_TYPE_COLUMN_NAME);
+        Long timestampColumnId = fColumns.get(TIMESTAMP_COLUMN_NAME);
+
+        assertNotNull(timestampColumnId);
+        assertNotNull(eventTypeColumnId);
+
+        // Query for the index for the first matching event
+        VirtualTableQueryFilter queryFilter = new EventTableQueryFilter(Arrays.asList(eventTypeColumnId, timestampColumnId), 0, 1, null);
+        Map<String, Object> parameters = FetchParametersUtils.virtualTableQueryToMap(queryFilter);
+
+        Map<Long, String> searchExpressions = new HashMap<>();
+        searchExpressions.put(eventTypeColumnId, "Does not exits");
+
+        parameters.put(TmfEventTableDataProvider.TABLE_SEARCH_EXPRESSION_KEY, searchExpressions);
+        parameters.put(TmfEventTableDataProvider.TABLE_SEARCH_DIRECTION_KEY, Direction.NEXT.name());
+
+        List<Long> expectedColumnsId = Arrays.asList(eventTypeColumnId, timestampColumnId);
+        TmfTimestampFormat.getDefaulTimeFormat().format(TmfTimestamp.fromMillis(2).toNanos());
+        List<EventTableLine> expectedData = Collections.emptyList();
+
+        TmfModelResponse<ITmfVirtualTableModel<EventTableLine>> response = fProvider.fetchLines(parameters, null);
+        ITmfVirtualTableModel<EventTableLine> currentModel = response.getModel();
+        currentModel = response.getModel();
+        assertNotNull(currentModel);
+        assertTrue(currentModel.getLines().isEmpty());
+        TmfVirtualTableModel<@NonNull EventTableLine> expectedModel = new TmfVirtualTableModel<>(expectedColumnsId, expectedData, 0, 10000);
+        assertEquals(expectedModel, currentModel);
+    }
+
+    /**
      * Given a start index, count and a list of desired columns, we check model
-     * returned by the data provider. We also apply a search filter on a single column.
+     * returned by the data provider. We also apply a search filter on a single
+     * column to search NEXT from the start index.
      */
     @Test
     public void testDataProviderWithSimpleSingleColumnsSearch() {
@@ -340,7 +377,7 @@
         searchExpressions.put(eventTypeColumnId, "Type-2");
 
         parameters.put(TmfEventTableDataProvider.TABLE_SEARCH_EXPRESSION_KEY, searchExpressions);
-        parameters.put(DataProviderParameterUtils.FILTERED_KEY, true);
+        parameters.put(TmfEventTableDataProvider.TABLE_SEARCH_DIRECTION_KEY, Direction.NEXT.name());
 
         List<Long> expectedColumnsId = Arrays.asList(eventTypeColumnId, timestampColumnId);
         TmfTimestampFormat.getDefaulTimeFormat().format(TmfTimestamp.fromMillis(2).toNanos());
@@ -351,7 +388,7 @@
         TmfModelResponse<ITmfVirtualTableModel<EventTableLine>> response = fProvider.fetchLines(parameters, null);
         ITmfVirtualTableModel<EventTableLine> currentModel = response.getModel();
 
-        TmfVirtualTableModel<@NonNull EventTableLine> expectedModel = new TmfVirtualTableModel<>(expectedColumnsId, expectedData, 0, 10000);
+        TmfVirtualTableModel<@NonNull EventTableLine> expectedModel = new TmfVirtualTableModel<>(expectedColumnsId, expectedData, 2, 10000);
         assertEquals(expectedModel, currentModel);
 
         // Query for events with search filter active. Matching lines will be tagged for highlighting
@@ -377,6 +414,127 @@
 
     /**
      * Given a start index, count and a list of desired columns, we check model
+     * returned by the data provider. We also apply a search filter on a single
+     * column to search NEXT from the start index. N number of events from
+     * the first matched event will be returned by the data provider.
+     */
+    @Test
+    public void testDataProviderWithGetDataFromSearchForwardMatch() {
+        Long eventTypeColumnId = fColumns.get(EVENT_TYPE_COLUMN_NAME);
+        Long timestampColumnId = fColumns.get(TIMESTAMP_COLUMN_NAME);
+
+        assertNotNull(timestampColumnId);
+        assertNotNull(eventTypeColumnId);
+
+        // Query for the index for the first matching event
+        int nbEventsRequested = 3;
+        VirtualTableQueryFilter queryFilter = new EventTableQueryFilter(Arrays.asList(eventTypeColumnId, timestampColumnId), 0, nbEventsRequested, null);
+        Map<String, Object> parameters = FetchParametersUtils.virtualTableQueryToMap(queryFilter);
+
+        Map<Long, String> searchExpressions = new HashMap<>();
+        searchExpressions.put(eventTypeColumnId, "Type-2");
+
+        parameters.put(TmfEventTableDataProvider.TABLE_SEARCH_EXPRESSION_KEY, searchExpressions);
+        parameters.put(TmfEventTableDataProvider.TABLE_SEARCH_DIRECTION_KEY, Direction.NEXT.name());
+
+        List<Long> expectedColumnsId = Arrays.asList(eventTypeColumnId, timestampColumnId);
+        TmfTimestampFormat.getDefaulTimeFormat().format(TmfTimestamp.fromMillis(2).toNanos());
+        List<EventTableLine> expectedData = Arrays.asList(
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-2"), new VirtualTableCell(lineTimestamp(3))), 2, TmfTimestamp.fromMillis(3), 2, 0),
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-3"), new VirtualTableCell(lineTimestamp(4))), 3, TmfTimestamp.fromMillis(4), 3, 0),
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-4"), new VirtualTableCell(lineTimestamp(5))), 4, TmfTimestamp.fromMillis(5), 4, 0));
+        expectedData.get(0).setActiveProperties(CoreFilterProperty.HIGHLIGHT);
+
+        TmfModelResponse<ITmfVirtualTableModel<EventTableLine>> response = fProvider.fetchLines(parameters, null);
+        ITmfVirtualTableModel<EventTableLine> currentModel = response.getModel();
+
+        TmfVirtualTableModel<@NonNull EventTableLine> expectedModel = new TmfVirtualTableModel<>(expectedColumnsId, expectedData, 2, 10000);
+        assertNotNull(currentModel);
+        assertEquals(nbEventsRequested, currentModel.getLines().size());
+        assertEquals(expectedModel, currentModel);
+    }
+
+    /**
+     * Given a start index, count and a list of desired columns, we check model
+     * returned by the data provider. We also apply a search filter on a single column
+     * with search direction PREVIOUS.
+     */
+    @Test
+    public void testDataProviderWithSimpleSingleColumnsIndexBackwardsSearch() {
+        Long eventTypeColumnId = fColumns.get(EVENT_TYPE_COLUMN_NAME);
+        Long timestampColumnId = fColumns.get(TIMESTAMP_COLUMN_NAME);
+
+        assertNotNull(timestampColumnId);
+        assertNotNull(eventTypeColumnId);
+
+        // Query for the index for the first matching event backwards, starting at index 10
+        VirtualTableQueryFilter queryFilter = new EventTableQueryFilter(Arrays.asList(eventTypeColumnId, timestampColumnId), 10, 1, null);
+        Map<String, Object> parameters = FetchParametersUtils.virtualTableQueryToMap(queryFilter);
+
+        Map<Long, String> searchExpressions = new HashMap<>();
+        searchExpressions.put(eventTypeColumnId, "Type-2");
+
+        parameters.put(TmfEventTableDataProvider.TABLE_SEARCH_EXPRESSION_KEY, searchExpressions);
+        parameters.put(TmfEventTableDataProvider.TABLE_SEARCH_DIRECTION_KEY, Direction.PREVIOUS.name());
+
+        List<Long> expectedColumnsId = Arrays.asList(eventTypeColumnId, timestampColumnId);
+        TmfTimestampFormat.getDefaulTimeFormat().format(TmfTimestamp.fromMillis(2).toNanos());
+        List<EventTableLine> expectedData = Arrays.asList(
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-2"), new VirtualTableCell(lineTimestamp(10))), 9, TmfTimestamp.fromMillis(10), 9, 0));
+        expectedData.get(0).setActiveProperties(CoreFilterProperty.HIGHLIGHT);
+
+        TmfModelResponse<ITmfVirtualTableModel<EventTableLine>> response = fProvider.fetchLines(parameters, null);
+        ITmfVirtualTableModel<EventTableLine> currentModel = response.getModel();
+
+        TmfVirtualTableModel<@NonNull EventTableLine> expectedModel = new TmfVirtualTableModel<>(expectedColumnsId, expectedData, 9, 10000);
+        assertEquals(expectedModel, currentModel);
+    }
+
+    /**
+     * Given a start index, count and a list of desired columns, we check model
+     * returned by the data provider. We also apply a search filter on a single
+     * column to search PREVIOUS from the start index. N number of events from
+     * the first matched event will be returned by the data provider.
+     */
+    @Test
+    public void testDataProviderWithGetDataFromSearchBackwardsMatch() {
+        Long eventTypeColumnId = fColumns.get(EVENT_TYPE_COLUMN_NAME);
+        Long timestampColumnId = fColumns.get(TIMESTAMP_COLUMN_NAME);
+
+        assertNotNull(timestampColumnId);
+        assertNotNull(eventTypeColumnId);
+
+        // Query for the 3 events starting from the the first matching event backwards, starting at index 10
+        int nbEventsRequested = 3;
+        VirtualTableQueryFilter queryFilter = new EventTableQueryFilter(Arrays.asList(eventTypeColumnId, timestampColumnId), 10, nbEventsRequested, null);
+        Map<String, Object> parameters = FetchParametersUtils.virtualTableQueryToMap(queryFilter);
+
+        Map<Long, String> searchExpressions = new HashMap<>();
+        searchExpressions.put(eventTypeColumnId, "Type-2");
+
+        parameters.put(TmfEventTableDataProvider.TABLE_SEARCH_EXPRESSION_KEY, searchExpressions);
+        parameters.put(TmfEventTableDataProvider.TABLE_SEARCH_DIRECTION_KEY, Direction.PREVIOUS.name());
+
+        List<Long> expectedColumnsId = Arrays.asList(eventTypeColumnId, timestampColumnId);
+        TmfTimestampFormat.getDefaulTimeFormat().format(TmfTimestamp.fromMillis(2).toNanos());
+        List<EventTableLine> expectedData = Arrays.asList(
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-2"), new VirtualTableCell(lineTimestamp(10))), 9, TmfTimestamp.fromMillis(10), 9, 0),
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-3"), new VirtualTableCell(lineTimestamp(11))), 10, TmfTimestamp.fromMillis(11), 10, 0),
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-4"), new VirtualTableCell(lineTimestamp(12))), 11, TmfTimestamp.fromMillis(12), 11, 0));
+        expectedData.get(0).setActiveProperties(CoreFilterProperty.HIGHLIGHT);
+
+        TmfModelResponse<ITmfVirtualTableModel<EventTableLine>> response = fProvider.fetchLines(parameters, null);
+        ITmfVirtualTableModel<EventTableLine> currentModel = response.getModel();
+
+        TmfVirtualTableModel<@NonNull EventTableLine> expectedModel = new TmfVirtualTableModel<>(expectedColumnsId, expectedData, 9, 10000);
+        assertNotNull(currentModel);
+        assertEquals(nbEventsRequested, currentModel.getLines().size());
+        assertEquals(expectedModel, currentModel);
+    }
+
+
+    /**
+     * Given a start index, count and a list of desired columns, we check model
      * returned by the data provider. We also apply a search filter on multiple columns
      */
     @Test
@@ -396,7 +554,7 @@
         searchExpressions.put(timestampColumnId, "\\d*4\\d*s*");
 
         parameters.put(TmfEventTableDataProvider.TABLE_SEARCH_EXPRESSION_KEY, searchExpressions);
-        parameters.put(DataProviderParameterUtils.FILTERED_KEY, true);
+        parameters.put(TmfEventTableDataProvider.TABLE_SEARCH_DIRECTION_KEY, Direction.NEXT.name());
 
         List<Long> expectedColumnsId = new ArrayList<>(fColumns.values());
         TmfTimestampFormat.getDefaulTimeFormat().format(TmfTimestamp.fromMillis(2).toNanos());
@@ -407,7 +565,7 @@
         TmfModelResponse<ITmfVirtualTableModel<EventTableLine>> response = fProvider.fetchLines(parameters, null);
         ITmfVirtualTableModel<EventTableLine> currentModel = response.getModel();
 
-        TmfVirtualTableModel<@NonNull EventTableLine> expectedModel = new TmfVirtualTableModel<>(expectedColumnsId, expectedData, 0, 10000);
+        TmfVirtualTableModel<@NonNull EventTableLine> expectedModel = new TmfVirtualTableModel<>(expectedColumnsId, expectedData, 3, 10000);
         assertEquals(expectedModel, currentModel);
 
         // Query for events with search filter active. Matching lines will be tagged for highlighting
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/events/TmfEventTableDataProvider.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/events/TmfEventTableDataProvider.java
index e312079..bd0ac89 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/events/TmfEventTableDataProvider.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/events/TmfEventTableDataProvider.java
@@ -18,13 +18,16 @@
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.TreeMap;
 import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.Predicate;
 
 import org.apache.commons.lang3.StringUtils;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.common.core.NonNullUtils;
 import org.eclipse.tracecompass.internal.provisional.tmf.core.model.filters.VirtualTableQueryFilter;
 import org.eclipse.tracecompass.internal.provisional.tmf.core.model.table.EventTableLine;
 import org.eclipse.tracecompass.internal.provisional.tmf.core.model.table.ITmfFilterModel;
@@ -37,6 +40,8 @@
 import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEventType;
 import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect;
 import org.eclipse.tracecompass.tmf.core.event.aspect.TmfBaseAspects;
 import org.eclipse.tracecompass.tmf.core.filter.FilterManager;
@@ -53,6 +58,7 @@
 import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest;
 import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
+import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
@@ -62,6 +68,7 @@
 import com.google.common.collect.BiMap;
 import com.google.common.collect.HashBiMap;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
 
 /**
  * This data provider will return a virtual table model (wrapped in a response)
@@ -77,10 +84,9 @@
      */
     public static final String TABLE_SEARCH_EXPRESSION_KEY = "table_search_expressions"; //$NON-NLS-1$
     /**
-     * Key for table search to get index of search
+     * Key for table search direction (forward or backward)
      */
-    public static final String TABLE_SEARCH_INDEX_KEY = "table_search_index"; //$NON-NLS-1$
-
+    public static final String TABLE_SEARCH_DIRECTION_KEY = "table_search_direction"; //$NON-NLS-1$
     /**
      * Key for table filters
      */
@@ -94,9 +100,11 @@
     private @Nullable ITmfFilter fFilter;
 
     /**
-     * Maps used for the optimization of filtered query. TODO: Since these map can
-     * take a lot of memory, one solution would be to replace these maps by two
-     * lists and use binary search instead of TreeMap floor
+     * Maps used for the optimization of filtered query.
+     *
+     * TODO: Since these map can take a lot of memory, one solution would be to
+     * replace these maps by two lists and use binary search instead of TreeMap
+     * floor.
      */
     private TreeMap<Long, Long> fIndexToRankMap = new TreeMap<>();
     private TreeMap<Long, Long> fRankToIndexMap = new TreeMap<>();
@@ -126,6 +134,17 @@
     private static final int INDEX_STORING_INTERVAL = 1000;
 
     /**
+     * Direction of search, navigation etc.
+     * @since 7.1
+     */
+    public enum Direction {
+        /** Search next */
+        NEXT,
+        /** Search previous*/
+        PREVIOUS
+    }
+
+    /**
      * Constructor
      *
      * @param trace
@@ -180,24 +199,73 @@
         @Nullable TmfCollapseFilter collapseFilter = extractCollapseFilter(fetchParameters);
         Map<Long, ITmfEventAspect<?>> aspects = getAspectsFromColumnsId(queryFilter.getColumnsId());
 
-        Boolean isFiltered = DataProviderParameterUtils.extractIsFiltered(fetchParameters);
-        boolean isIndexRequest = isFiltered != null && isFiltered;
-
         if (aspects.isEmpty()) {
-            return new TmfModelResponse<>(new TmfVirtualTableModel<EventTableLine>(Collections.emptyList(), Collections.emptyList(), queryFilter.getIndex(), 0), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
+            return new TmfModelResponse<>(new TmfVirtualTableModel<>(Collections.emptyList(), Collections.emptyList(), queryFilter.getIndex(), 0), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
         }
         List<Long> columnsIds = new ArrayList<>(aspects.keySet());
         if (getTrace().getNbEvents() == 0) {
             return new TmfModelResponse<>(new TmfVirtualTableModel<>(columnsIds, Collections.emptyList(), queryFilter.getIndex(), 0), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
         }
 
-        boolean forwardSearch = queryFilter.getCount() >= 0;
+        /*
+         * Search for the next or previous event starting from the given event index
+         */
+        Object directionValue = fetchParameters.get(TABLE_SEARCH_DIRECTION_KEY);
 
+        /////////////////////////////////////
+        // TODO remove isFiltered when Theia front-end is updated to use TABLE_SEARCH_DIRECTION_KEY instead
+        Boolean isFiltered = DataProviderParameterUtils.extractIsFiltered(fetchParameters);
+        boolean isIndexRequest = isFiltered != null && isFiltered;
+        if (isIndexRequest && directionValue == null) {
+            directionValue = Direction.NEXT.name();
+        }
+        /////////////////////////////////////
+
+        if (searchFilter != null && directionValue != null) {
+            Direction direction = directionValue.equals(Direction.PREVIOUS.name()) ? Direction.PREVIOUS : Direction.NEXT;
+            @Nullable WrappedEvent event = null;
+            Predicate<@NonNull ITmfEvent> predicate;
+            if (filter == null) {
+                predicate = searchFilter::matches;
+            } else {
+                predicate = e -> (filter.matches(e) && searchFilter.matches(e));
+            }
+            if (direction == Direction.NEXT) {
+                event = getNextWrappedEventMatching(getTrace(), Math.abs(queryFilter.getIndex()), predicate, monitor);
+            } else if (direction == Direction.PREVIOUS) {
+                event = getPreviousWrappedEventMatching(getTrace(), Math.abs(queryFilter.getIndex()), predicate, monitor);
+            }
+            List<EventTableLine> lines = new ArrayList<>();
+            long rank = queryFilter.getIndex();
+            if (event != null) {
+                rank = event.getRank();
+                // create new queryFilter with updated start rank to get number of events starting from first matching event
+                queryFilter = new VirtualTableQueryFilter(queryFilter.getColumnsId(), rank, queryFilter.getCount());
+                lines.add(buildEventTableLine(aspects, event.getOriginalEvent(), rank, rank, true));
+            }
+            if ((queryFilter.getCount() == 1) || (event == null)) {
+                /**
+                 * If no event was found or the number of requested events is one
+                 * reply here since all required data for the reply is available.
+                 */
+                TmfVirtualTableModel<EventTableLine> model = new TmfVirtualTableModel<>(columnsIds, lines, rank, getTrace().getNbEvents());
+                return new TmfModelResponse<>(model, ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
+            }
+        }
+
+        /*
+         * Collect queryFilter.getCount() number of events from start rank
+         */
+
+        /*
+         * TODO implement upper limit of queryFilter.getCount() to avoid running out of memory.
+         * TBD if the check and should be handled here or in the calling methods.
+         */
         TableEventRequest request;
         if (filter != null) {
-            request = filteredTableRequest(Math.abs(queryFilter.getCount()), queryFilter.getIndex(), aspects, filter, searchFilter, forwardSearch, collapseFilter, monitor);
+            request = filteredTableRequest(Math.abs(queryFilter.getCount()), queryFilter.getIndex(), aspects, filter, searchFilter, collapseFilter, monitor);
         } else {
-            request = tableRequest(Math.abs(queryFilter.getCount()), queryFilter.getIndex(), aspects, searchFilter, forwardSearch, collapseFilter, isIndexRequest,  monitor);
+            request = tableRequest(Math.abs(queryFilter.getCount()), queryFilter.getIndex(), aspects, searchFilter, collapseFilter, monitor);
             request.setEventCount(getTrace().getNbEvents());
         }
 
@@ -205,13 +273,11 @@
         try {
             request.waitForCompletion();
         } catch (InterruptedException e) {
-            return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, e.getMessage());
+            return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, NonNullUtils.nullToEmptyString(e.getMessage()));
         }
-
         if (request.isCancelled()) {
             return new TmfModelResponse<>(null, ITmfResponse.Status.CANCELLED, CommonStatusMessage.TASK_CANCELLED);
         }
-
         TmfVirtualTableModel<EventTableLine> model = new TmfVirtualTableModel<>(columnsIds, request.getEventLines(), queryFilter.getIndex(), request.getCurrentCount());
         return new TmfModelResponse<>(model, ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
     }
@@ -293,7 +359,7 @@
         try {
             request.waitForCompletion();
         } catch (InterruptedException e) {
-            return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, e.getMessage());
+            return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, NonNullUtils.nullToEmptyString(e.getMessage()));
         }
 
         return new TmfModelResponse<>(foundIndex, ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
@@ -325,12 +391,31 @@
         }
     }
 
+    /**
+     * Create a table event request that fills a list of {@link EventTableLine}
+     * based on the query parameters and based on a filter.
+     *
+     * @param queryCount
+     *            number of requested events
+     * @param queryIndex
+     *            start rank to start looking for requested events
+     * @param aspects
+     *            Aspects to resolve
+     * @param filter
+     *            The filter to apply
+     * @param searchFilter
+     *            Search filter used to tag event lines
+     * @param collapseFilter
+     *            The collapse filter to apply
+     * @param monitor
+     *            a progress monitor
+     * @return a {@link TableEventRequest} to fill a list of {@link EventTableLine}
+     */
     private TableEventRequest filteredTableRequest(int queryCount,
             long queryIndex,
             Map<Long, ITmfEventAspect<?>> aspects,
             ITmfFilter filter,
             @Nullable ITmfFilter searchFilter,
-            boolean forwardSearch,
             @Nullable ITmfFilter collapseFilter,
             @Nullable IProgressMonitor monitor) {
 
@@ -354,15 +439,13 @@
 
                 List<EventTableLine> events = getEventLines();
                 if (filter.matches(event) && (collapseFilter == null || collapseFilter.matches(event))) {
-                    if (searchFilter == null || searchFilter.matches(event)) {
-                        if (events.size() < queryCount && queryIndex <= currentIndex) {
-                            // FIXME: searching while filtering
-                            events.add(buildEventTableLine(aspects, event, currentIndex, rank, false));
-                        }
-                        if (currentIndex % INDEX_STORING_INTERVAL == 0) {
-                            fIndexToRankMap.put(currentIndex, rank);
-                            fRankToIndexMap.put(rank, currentIndex);
-                        }
+                    boolean matches = searchFilter != null && searchFilter.matches(event);
+                    if (events.size() < queryCount && queryIndex <= currentIndex) {
+                        events.add(buildEventTableLine(aspects, event, currentIndex, rank, matches));
+                    }
+                    if (currentIndex % INDEX_STORING_INTERVAL == 0) {
+                        fIndexToRankMap.put(currentIndex, rank);
+                        fRankToIndexMap.put(rank, currentIndex);
                     }
                     currentIndex++;
                     incrementCount();
@@ -375,10 +458,15 @@
                     events.set(lastIndex, new EventTableLine(prevLine.getCells(), prevLine.getIndex(), prevLine.getTimestamp(), prevLine.getRank(), prevRepeatCount++));
                 }
 
-                if (searchFilter != null && ((!forwardSearch && getCurrentCount() == queryCount) || events.size() == queryCount)) {
-                    done();
-                    return;
-                }
+                /*
+                 *  FIXME: Right now the whole trace is read to determine the number of matched events.
+                 *  In case of search filter being present, it only starts counting from the first
+                 *  matched event and the total number of filtered event is incorrect.
+                 *
+                 *  However, the number of matched events should only be done once per filter and
+                 *  after the filter changed. Implement way to determine the number of matched events.
+                 */
+
                 rank++;
             }
 
@@ -393,13 +481,29 @@
         };
     }
 
+    /**
+     * Create a table event request that fills a list of {@link EventTableLine}
+     * based on the query parameters.
+     *
+     * @param queryCount
+     *            number of requested events
+     * @param queryIndex
+     *            start rank to start looking for requested events
+     * @param aspects
+     *            Aspects to resolve
+     * @param searchFilter
+     *            Search filter used to tag event lines
+     * @param collapseFilter
+     *            The collapse filter to apply
+     * @param monitor
+     *            a progress monitor
+     * @return a {@link TableEventRequest} to fill a list of {@link EventTableLine}
+     */
     private TableEventRequest tableRequest(int queryCount,
             long queryIndex,
             Map<Long, ITmfEventAspect<?>> aspects,
             @Nullable ITmfFilter searchFilter,
-            boolean forwardSearch,
             @Nullable ITmfFilter collapseFilter,
-            boolean isIndexRequest,
             @Nullable IProgressMonitor monitor) {
 
         return new TableEventRequest(queryIndex) {
@@ -415,11 +519,11 @@
 
                 List<EventTableLine> events = getEventLines();
                 boolean matches = searchFilter != null && searchFilter.matches(event);
-                if ((!isIndexRequest || matches) && (collapseFilter == null || collapseFilter.matches(event))) {
+                if (collapseFilter == null || collapseFilter.matches(event)) {
                     if (events.size() < queryCount) {
                         events.add(buildEventTableLine(aspects, event, rank, rank, matches));
                     }
-                } else if (collapseFilter != null && !events.isEmpty()) {
+                } else if (!events.isEmpty()) {
                     // If a collapse filter is present, we need to update the last event we have in
                     // our list to increment the repeat count value.
                     int lastIndex = events.size() - 1;
@@ -428,7 +532,7 @@
                     events.set(lastIndex, new EventTableLine(prevLine.getCells(), prevLine.getIndex(), prevLine.getTimestamp(), prevLine.getRank(), prevRepeatCount++));
                 }
 
-                if ((searchFilter != null && !forwardSearch && getNbRead() == queryCount) || events.size() == queryCount) {
+                if ((getNbRead() == queryCount) || events.size() == queryCount) {
                     done();
                     return;
                 }
@@ -471,6 +575,7 @@
      *            Filter to apply
      */
     private void applyFilter(ITmfFilter filter) {
+        // TODO verify if this works correctly
         if (!filter.equals(fFilter)) {
             fFilter = filter;
             fIndexToRankMap.clear();
@@ -548,7 +653,7 @@
     }
 
     @SuppressWarnings("unchecked")
-    private @Nullable static ITmfFilter extractSearchFilter(Map<String, Object> fetchParameters) {
+    private static @Nullable ITmfFilter extractSearchFilter(Map<String, Object> fetchParameters) {
         Object searchFilterObject = fetchParameters.get(TABLE_SEARCH_EXPRESSION_KEY);
         if (searchFilterObject instanceof Map<?, ?>) {
             return extractSimpleSearchFilter((Map<?, String>) searchFilterObject);
@@ -556,7 +661,7 @@
         return null;
     }
 
-    private @Nullable static ITmfFilter extractSimpleSearchFilter (Map<?, String> searchMap) {
+    private static @Nullable ITmfFilter extractSimpleSearchFilter (Map<?, String> searchMap) {
         if (searchMap.isEmpty()) {
             return null;
         }
@@ -670,4 +775,270 @@
         }
         return commonTraceType != null;
     }
+
+
+    /**
+     * Retrieve from a trace the next event, from a starting rank, matching the
+     * given predicate.
+     *
+     * Code inspired from TmfTraceUtils implementation, however this will return
+     * a {@link WrappedEvent} with the correct event rank.
+     *
+     * @param trace
+     *            The trace
+     * @param startRank
+     *            The rank of the event at which to start searching. Use
+     *            <code>0</code> to search from the start of the trace.
+     * @param predicate
+     *            The predicate to test events against
+     * @param monitor
+     *            Optional progress monitor that can be used to cancel the operation
+     * @return The first {@link WrappedEvent} matching the predicate, or null if the end of the
+     *         trace was reached and no event was found
+     */
+    private static @Nullable WrappedEvent getNextWrappedEventMatching(ITmfTrace trace, long startRank,
+            Predicate<ITmfEvent> predicate, @Nullable IProgressMonitor monitor) {
+        if (monitor != null && monitor.isCanceled()) {
+            return null;
+        }
+
+        /*
+         * startRank + 1 because we do not want to include the start event itself in the
+         * search
+         */
+        EventMatchingRequest req = new EventMatchingRequest(startRank + 1, predicate, monitor);
+        trace.sendRequest(req);
+        try {
+            req.waitForCompletion();
+        } catch (InterruptedException e) {
+            return null;
+        }
+
+        return req.getFoundEvent();
+    }
+
+    /**
+     * Retrieve from a trace the previous event, from a given rank, matching the
+     * given predicate.
+     *
+     * Code inspired from TmfTraceUtils implementation, however this will return
+     * a {@link WrappedEvent} with the correct event rank.
+     *
+     * @param trace
+     *            The trace
+     * @param startRank
+     *            The rank of the event at which to start searching backwards.
+     * @param predicate
+     *            The predicate to test events against
+     * @param monitor
+     *            Optional progress monitor that can be used to cancel the operation
+     * @return The first {@link WrappedEvent} found matching the predicate, or null if the
+     *         beginning of the trace was reached and no event was found
+     */
+    private static @Nullable WrappedEvent getPreviousWrappedEventMatching(ITmfTrace trace, long startRank,
+            Predicate<ITmfEvent> predicate, @Nullable IProgressMonitor monitor) {
+        if (monitor != null && monitor.isCanceled()) {
+            return null;
+        }
+        /*
+         * We are going to do a series of queries matching the trace's cache size in
+         * length (which should minimize on-disk seeks), then iterate on the found
+         * events in reverse order until we find a match.
+         */
+        int step = trace.getCacheSize();
+
+        /*
+         * If we are close to the beginning of the trace, make sure we only look for the
+         * events before the startRank.
+         */
+        if (startRank < step) {
+            step = (int) startRank;
+        }
+
+        long currentRank = startRank;
+        try {
+            while (currentRank > 0) {
+                currentRank = Math.max(currentRank - step, 0);
+
+                List<WrappedEvent> list = new ArrayList<>(step);
+                ArrayFillingRequest req = new ArrayFillingRequest(currentRank, step, list, monitor);
+                trace.sendRequest(req);
+
+                /* Check periodically if the job was cancelled */
+                req.waitForCompletion();
+
+                Optional<WrappedEvent> matchingEvent = Lists.reverse(list).stream()
+                        .filter(e -> predicate.test(e.getOriginalEvent()))
+                        .findFirst();
+
+                if (matchingEvent.isPresent()) {
+                    /* We found an event matching, return it! */
+                    return matchingEvent.get();
+                }
+                /* Keep searching, next loop */
+
+            }
+        } catch (InterruptedException e) {
+            return null;
+        }
+
+        /*
+         * We searched up to the beginning of the trace and didn't find anything.
+         */
+        return null;
+
+    }
+
+    /**
+     * Event request looking for an event matching a Predicate.
+     */
+    private static class EventMatchingRequest extends TmfEventRequest {
+
+        private final Predicate<ITmfEvent> fPredicate;
+        private final @Nullable IProgressMonitor fMonitor;
+
+        private @Nullable WrappedEvent fFoundEvent = null;
+
+        /**
+         * Basic constructor, will query the trace until the end.
+         *
+         * @param startRank
+         *            The rank at which to start, use 0 for the beginning
+         * @param predicate
+         *            The predicate to test against each event
+         * @param monitor
+         *            an optional progress monitor
+         */
+        public EventMatchingRequest(long startRank, Predicate<ITmfEvent> predicate, @Nullable IProgressMonitor monitor) {
+            super(ITmfEvent.class, startRank, ALL_DATA, ExecutionType.FOREGROUND);
+            fPredicate = predicate;
+            fMonitor = monitor;
+        }
+
+        /**
+         * Basic constructor, will query the trace the limit is reached.
+         *
+         * @param startRank
+         *            The rank at which to start, use 0 for the beginning
+         * @param limit
+         *            The limit on the number of events
+         * @param predicate
+         *            The predicate to test against each event
+         * @param monitor
+         *            an optional progress monitor
+         */
+        public EventMatchingRequest(long startRank, int limit, Predicate<ITmfEvent> predicate, @Nullable IProgressMonitor monitor) {
+            super(ITmfEvent.class, startRank, limit, ExecutionType.FOREGROUND);
+            fPredicate = predicate;
+            fMonitor = monitor;
+        }
+
+        public @Nullable WrappedEvent getFoundEvent() {
+            return fFoundEvent;
+        }
+
+        @Override
+        public void handleData(ITmfEvent event) {
+            super.handleData(event);
+            if (fPredicate.test(event)) {
+                fFoundEvent = new WrappedEvent(event, getNbRead() + getIndex() - 1);
+                done();
+            }
+            if (fMonitor != null && fMonitor.isCanceled()) {
+                cancel();
+            }
+        }
+    }
+
+    /**
+     * Event request that simply puts all returned events into a list passed in
+     * parameter.
+     */
+    private static class ArrayFillingRequest extends TmfEventRequest {
+
+        private final List<WrappedEvent> fList;
+        private final @Nullable IProgressMonitor fMonitor;
+
+        public ArrayFillingRequest(long startRank, int limit, List<WrappedEvent> listToFill, @Nullable IProgressMonitor monitor) {
+            super(ITmfEvent.class, startRank, limit, ExecutionType.FOREGROUND);
+            fList = listToFill;
+            fMonitor = monitor;
+        }
+
+        @Override
+        public void handleData(ITmfEvent event) {
+            super.handleData(event);
+            fList.add(new WrappedEvent(event, getIndex() + getNbRead() - 1));
+            if (fMonitor != null && fMonitor.isCanceled()) {
+                cancel();
+            }
+        }
+    }
+
+    /**
+     * A TMF Events wrapper class wrapping a ITmfEvent and the corresponding, valid rank.
+     */
+    private static class WrappedEvent implements ITmfEvent {
+        /**
+         * Event reference.
+         */
+        ITmfEvent fEvent;
+        /**
+         * Events rank.
+         */
+        long fRank;
+
+        /**
+         * Constructor for new cached events.
+         *
+         * @param tmfEvent
+         *            The original trace event
+         * @param rank
+         *            The rank of this event in the trace
+         */
+        public WrappedEvent (ITmfEvent tmfEvent, long rank) {
+            this.fEvent = tmfEvent;
+            this.fRank = rank;
+        }
+
+        public ITmfEvent getOriginalEvent() {
+            return fEvent;
+        }
+
+        @Override
+        public @Nullable <T> T getAdapter(@Nullable Class<T> adapterType) {
+            return fEvent.getAdapter(adapterType);
+        }
+
+        @Override
+        public ITmfTrace getTrace() {
+            return fEvent.getTrace();
+        }
+
+        @Override
+        public long getRank() {
+            return fRank;
+        }
+
+        @Override
+        public String getName() {
+            return fEvent.getName();
+        }
+
+        @Override
+        public ITmfTimestamp getTimestamp() {
+            return fEvent.getTimestamp();
+        }
+
+        @Override
+        public @Nullable ITmfEventType getType() {
+            return fEvent.getType();
+        }
+
+        @Override
+        public @Nullable ITmfEventField getContent() {
+            return fEvent.getContent();
+        }
+    }
+
 }
\ No newline at end of file
