Merge branch 'master' into 'trace-server'

Change-Id: I7358063bd2d2ee0b59dcf1c3d8d96d292fed02d5
Signed-off-by: Simon Delisle <simon.delisle@ericsson.com>
diff --git a/analysis/org.eclipse.tracecompass.analysis.counters.core/src/org/eclipse/tracecompass/internal/analysis/counters/core/CounterDataProvider.java b/analysis/org.eclipse.tracecompass.analysis.counters.core/src/org/eclipse/tracecompass/internal/analysis/counters/core/CounterDataProvider.java
index db3c686..dba882a 100644
--- a/analysis/org.eclipse.tracecompass.analysis.counters.core/src/org/eclipse/tracecompass/internal/analysis/counters/core/CounterDataProvider.java
+++ b/analysis/org.eclipse.tracecompass.analysis.counters.core/src/org/eclipse/tracecompass/internal/analysis/counters/core/CounterDataProvider.java
@@ -24,15 +24,16 @@
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.analysis.counters.core.CounterAnalysis;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.internal.tmf.core.model.xy.AbstractTreeCommonXDataProvider;
 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
 import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
 import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
 import org.eclipse.tracecompass.tmf.core.model.YModel;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectedCounterQueryFilter;
-import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
-import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeDataModel;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.model.xy.IYModel;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.core.trace.experiment.TmfExperiment;
@@ -58,6 +59,11 @@
     public static final String ID = "org.eclipse.tracecompass.analysis.counters.core.CounterDataProvider"; //$NON-NLS-1$
 
     /**
+     * Cumulative key to extract isCumulative from parameters map
+     */
+    public static final String CUMULATIVE_COUNTER_KEY = "isCumulative"; //$NON-NLS-1$
+
+    /**
      * Chart's title
      */
     private static final String TITLE = Objects.requireNonNull(Messages.CounterDataProvider_ChartTitle);
@@ -96,19 +102,19 @@
      * @since 1.2
      */
     @Override
-    protected List<TmfTreeDataModel> getTree(ITmfStateSystem ss, TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    protected TmfTreeModel<TmfTreeDataModel> getTree(ITmfStateSystem ss, Map<String, Object> parameters, @Nullable IProgressMonitor monitor) {
         List<TmfTreeDataModel> entries = new ArrayList<>();
         long rootId = getId(ITmfStateSystem.ROOT_ATTRIBUTE);
-        entries.add(new TmfTreeDataModel(rootId, -1, getTrace().getName()));
+        entries.add(new TmfTreeDataModel(rootId, -1, Collections.singletonList(getTrace().getName())));
 
-        addTreeViewerBranch(ss, rootId, CounterAnalysis.GROUPED_COUNTER_ASPECTS_ATTRIB, entries);
-        addTreeViewerBranch(ss, rootId, CounterAnalysis.UNGROUPED_COUNTER_ASPECTS_ATTRIB, entries);
+        addTreeViewerBranch(ss, rootId, Collections.singletonList(CounterAnalysis.GROUPED_COUNTER_ASPECTS_ATTRIB), entries);
+        addTreeViewerBranch(ss, rootId, Collections.singletonList(CounterAnalysis.UNGROUPED_COUNTER_ASPECTS_ATTRIB), entries);
 
-        return entries;
+        return new TmfTreeModel<>(Collections.emptyList(), entries);
     }
 
-    private void addTreeViewerBranch(ITmfStateSystem ss, long parentId, String branchName, List<TmfTreeDataModel> entries) {
-        int quark = ss.optQuarkAbsolute(branchName);
+    private void addTreeViewerBranch(ITmfStateSystem ss, long parentId, List<String> branchName, List<TmfTreeDataModel> entries) {
+        int quark = ss.optQuarkAbsolute(branchName.get(0));
         if (quark != ITmfStateSystem.INVALID_ATTRIBUTE && !ss.getSubAttributes(quark, false).isEmpty()) {
             long id = getId(quark);
             TmfTreeDataModel branch = new TmfTreeDataModel(id, parentId, branchName);
@@ -123,7 +129,7 @@
     private void addTreeViewerEntries(ITmfStateSystem ss, long parentId, int quark, List<TmfTreeDataModel> entries) {
         for (int childQuark : ss.getSubAttributes(quark, false)) {
             long id = getId(childQuark);
-            TmfTreeDataModel childBranch = new TmfTreeDataModel(id, parentId, ss.getAttributeName(childQuark));
+            TmfTreeDataModel childBranch = new TmfTreeDataModel(id, parentId, Collections.singletonList(ss.getAttributeName(childQuark)));
             entries.add(childBranch);
             addTreeViewerEntries(ss, id, childQuark, entries);
         }
@@ -133,17 +139,22 @@
      * @since 1.2
      */
     @Override
-    protected @Nullable Map<String, IYModel> getYModels(ITmfStateSystem ss, SelectionTimeQueryFilter filter,
+    protected @Nullable Map<String, IYModel> getYModels(ITmfStateSystem ss, Map<String, Object> fetchParameters,
             @Nullable IProgressMonitor monitor) throws StateSystemDisposedException {
-        if (filter instanceof SelectedCounterQueryFilter) {
-            SelectedCounterQueryFilter selection = (SelectedCounterQueryFilter) filter;
-            return internalFetch(ss, selection, monitor);
+        // Check if the parameters contain timeRequested and selectedItems
+        // isCumulative will be compute later
+        if (FetchParametersUtils.createSelectionTimeQuery(fetchParameters) != null) {
+            return internalFetch(ss, fetchParameters, monitor);
         }
         return Collections.emptyMap();
     }
 
-    private @Nullable Map<String, IYModel> internalFetch(ITmfStateSystem ss, SelectedCounterQueryFilter filter,
+    private @Nullable Map<String, IYModel> internalFetch(ITmfStateSystem ss, Map<String, Object> fetchParameters,
             @Nullable IProgressMonitor monitor) throws StateSystemDisposedException {
+        SelectedCounterQueryFilter filter = createCounterQuery(fetchParameters);
+        if (filter == null) {
+            return null;
+        }
         long stateSystemEndTime = ss.getCurrentEndTime();
         Collection<Long> times = extractRequestedTimes(ss, filter, stateSystemEndTime);
 
@@ -174,6 +185,21 @@
         return ySeries.build();
     }
 
+    private static @Nullable SelectedCounterQueryFilter createCounterQuery(Map<String, Object> parameters) {
+        List<Long> timeRequested = DataProviderParameterUtils.extractTimeRequested(parameters);
+        List<Long> selectedItems = DataProviderParameterUtils.extractSelectedItems(parameters);
+
+        if (timeRequested == null || selectedItems == null) {
+            return null;
+        }
+
+        Boolean isCumulativeParameter = DataProviderParameterUtils.extractBoolean(parameters, CUMULATIVE_COUNTER_KEY);
+        // If the cumulative parameter is not present in the parameters use
+        // "false" as default value
+        boolean isCumulative = isCumulativeParameter != null && isCumulativeParameter;
+        return new SelectedCounterQueryFilter(timeRequested, selectedItems, isCumulative);
+    }
+
     /**
      * Extracts an array of times that will be used for a 2D query. It extracts the
      * times based on the state system bounds, the requested time of the query
diff --git a/analysis/org.eclipse.tracecompass.analysis.counters.core/src/org/eclipse/tracecompass/internal/analysis/counters/core/CounterDataProviderFactory.java b/analysis/org.eclipse.tracecompass.analysis.counters.core/src/org/eclipse/tracecompass/internal/analysis/counters/core/CounterDataProviderFactory.java
index 375536d..7813ab9 100644
--- a/analysis/org.eclipse.tracecompass.analysis.counters.core/src/org/eclipse/tracecompass/internal/analysis/counters/core/CounterDataProviderFactory.java
+++ b/analysis/org.eclipse.tracecompass.analysis.counters.core/src/org/eclipse/tracecompass/internal/analysis/counters/core/CounterDataProviderFactory.java
@@ -11,12 +11,17 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
 
+import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.analysis.counters.core.CounterAnalysis;
+import org.eclipse.tracecompass.internal.tmf.core.model.DataProviderDescriptor;
 import org.eclipse.tracecompass.internal.tmf.core.model.xy.TmfTreeXYCompositeDataProvider;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor.ProviderType;
 import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderFactory;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
 import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeDataModel;
@@ -25,6 +30,9 @@
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
 
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+
 /**
  * Factory to create instances of the {@link ITmfTreeXYDataProvider}.
  * Uses the DataProviderFactory endpoint.
@@ -35,6 +43,14 @@
 public class CounterDataProviderFactory implements IDataProviderFactory {
 
     private static final String TITLE = Objects.requireNonNull(Messages.CounterDataProvider_ChartTitle);
+    private static final Predicate<? super ITmfTrace> PREDICATE = t -> !Iterables.isEmpty(TmfTraceUtils.getAnalysisModulesOfClass(t, CounterAnalysis.class));
+    private static final IDataProviderDescriptor DESCRIPTOR =
+            new DataProviderDescriptor.Builder()
+                        .setId(CounterDataProvider.ID)
+                        .setName(TITLE)
+                        .setDescription(Objects.requireNonNull(Messages.CounterDataProviderFactory_DescriptionText))
+                        .setProviderType(ProviderType.TREE_TIME_XY)
+                        .build();
 
     /**
      * @since 2.0
@@ -62,4 +78,10 @@
         return TmfTreeXYCompositeDataProvider.create(traces, TITLE, CounterDataProvider.ID);
     }
 
+    @Override
+    public Collection<IDataProviderDescriptor> getDescriptors(@NonNull ITmfTrace trace) {
+        Collection<ITmfTrace> traces = TmfTraceManager.getTraceSet(trace);
+        return Iterables.any(traces, PREDICATE) ? Collections.singletonList(DESCRIPTOR) : Collections.emptyList();
+    }
+
 }
diff --git a/analysis/org.eclipse.tracecompass.analysis.counters.core/src/org/eclipse/tracecompass/internal/analysis/counters/core/Messages.java b/analysis/org.eclipse.tracecompass.analysis.counters.core/src/org/eclipse/tracecompass/internal/analysis/counters/core/Messages.java
index 057ac27..4f64782 100644
--- a/analysis/org.eclipse.tracecompass.analysis.counters.core/src/org/eclipse/tracecompass/internal/analysis/counters/core/Messages.java
+++ b/analysis/org.eclipse.tracecompass.analysis.counters.core/src/org/eclipse/tracecompass/internal/analysis/counters/core/Messages.java
@@ -28,6 +28,15 @@
      * Chart's title for counters view
      */
     public static @Nullable String CounterDataProvider_ChartTitle;
+
+    /**
+     * Name text for the data provider to be shown to the user
+     */
+    public static @Nullable String CounterDataProviderFactory_Title;
+    /**
+     * Description text for the data provider
+     */
+    public static @Nullable String CounterDataProviderFactory_DescriptionText;
     static {
         // initialize resource bundle
         NLS.initializeMessages(BUNDLE_NAME, Messages.class);
diff --git a/analysis/org.eclipse.tracecompass.analysis.counters.core/src/org/eclipse/tracecompass/internal/analysis/counters/core/messages.properties b/analysis/org.eclipse.tracecompass.analysis.counters.core/src/org/eclipse/tracecompass/internal/analysis/counters/core/messages.properties
index 494231b..9b2f553 100644
--- a/analysis/org.eclipse.tracecompass.analysis.counters.core/src/org/eclipse/tracecompass/internal/analysis/counters/core/messages.properties
+++ b/analysis/org.eclipse.tracecompass.analysis.counters.core/src/org/eclipse/tracecompass/internal/analysis/counters/core/messages.properties
@@ -8,4 +8,6 @@
 ###############################################################################
 
 CounterAspect_HelpPrefix=Counter for
-CounterDataProvider_ChartTitle=Counters
\ No newline at end of file
+CounterDataProvider_ChartTitle=Counters
+CounterDataProviderFactory_Title=Counters
+CounterDataProviderFactory_DescriptionText=Show a tree of performance counters and XY series mapping the value of each counter to time
diff --git a/analysis/org.eclipse.tracecompass.analysis.counters.ui/src/org/eclipse/tracecompass/analysis/counters/ui/CounterChartViewer.java b/analysis/org.eclipse.tracecompass.analysis.counters.ui/src/org/eclipse/tracecompass/analysis/counters/ui/CounterChartViewer.java
index 645a30e..c7dc0f3 100644
--- a/analysis/org.eclipse.tracecompass.analysis.counters.ui/src/org/eclipse/tracecompass/analysis/counters/ui/CounterChartViewer.java
+++ b/analysis/org.eclipse.tracecompass.analysis.counters.ui/src/org/eclipse/tracecompass/analysis/counters/ui/CounterChartViewer.java
@@ -9,9 +9,14 @@
 
 package org.eclipse.tracecompass.analysis.counters.ui;
 
+import java.util.Map;
+
+import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.tracecompass.internal.analysis.counters.core.CounterDataProvider;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectedCounterQueryFilter;
+import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.linecharts.TmfFilteredXYChartViewer;
 import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.linecharts.TmfXYChartSettings;
@@ -48,8 +53,16 @@
         updateContent();
     }
 
+    @Deprecated
     @Override
     protected TimeQueryFilter createQueryFilter(long start, long end, int nb) {
         return new SelectedCounterQueryFilter(start, end, nb, getSelected(), fIsCumulative);
     }
+
+    @Override
+    protected @NonNull Map<String, Object> createQueryParameters(long start, long end, int nb) {
+        Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.selectionTimeQueryToMap(new SelectionTimeQueryFilter(start, end, nb, getSelected()));
+        parameters.put(CounterDataProvider.CUMULATIVE_COUNTER_KEY, fIsCumulative);
+        return parameters;
+    }
 }
diff --git a/analysis/org.eclipse.tracecompass.analysis.graph.core/src/org/eclipse/tracecompass/internal/analysis/graph/core/dataprovider/CriticalPathDataProvider.java b/analysis/org.eclipse.tracecompass.analysis.graph.core/src/org/eclipse/tracecompass/internal/analysis/graph/core/dataprovider/CriticalPathDataProvider.java
index 9af54fe..ec5dfc9 100644
--- a/analysis/org.eclipse.tracecompass.analysis.graph.core/src/org/eclipse/tracecompass/internal/analysis/graph/core/dataprovider/CriticalPathDataProvider.java
+++ b/analysis/org.eclipse.tracecompass.analysis.graph.core/src/org/eclipse/tracecompass/internal/analysis/graph/core/dataprovider/CriticalPathDataProvider.java
@@ -33,7 +33,8 @@
 import org.eclipse.tracecompass.internal.analysis.graph.core.base.TmfGraphStatistics;
 import org.eclipse.tracecompass.internal.analysis.graph.core.base.TmfGraphVisitor;
 import org.eclipse.tracecompass.internal.tmf.core.model.AbstractTmfTraceDataProvider;
-import org.eclipse.tracecompass.internal.tmf.core.model.filters.TimeGraphStateQueryFilter;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
+import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
 import org.eclipse.tracecompass.tmf.core.model.CommonStatusMessage;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
@@ -43,8 +44,10 @@
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphState;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphStateFilter;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphArrow;
+import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphRowModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphState;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.response.ITmfResponse.Status;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
@@ -119,8 +122,8 @@
     }
 
     @Override
-    public synchronized @NonNull TmfModelResponse<@NonNull List<@NonNull CriticalPathEntry>> fetchTree(
-            @NonNull TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public synchronized @NonNull TmfModelResponse<@NonNull TmfTreeModel<@NonNull CriticalPathEntry>> fetchTree(
+            Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         TmfGraph graph = fCriticalPathModule.getCriticalPath();
         if (graph == null) {
             return new TmfModelResponse<>(null, Status.RUNNING, CommonStatusMessage.RUNNING);
@@ -135,7 +138,7 @@
         for (CriticalPathEntry model : visitor.getEntries()) {
             fEntryMetadata.put(model.getId(), model.getMetadata());
         }
-        return new TmfModelResponse<>(visitor.getEntries(), Status.COMPLETED, CommonStatusMessage.COMPLETED);
+        return new TmfModelResponse<>(new TmfTreeModel<>(Collections.emptyList(), visitor.getEntries()), Status.COMPLETED, CommonStatusMessage.COMPLETED);
     }
 
     /**
@@ -163,7 +166,7 @@
     }
 
     @Override
-    public @NonNull TmfModelResponse<@NonNull List<@NonNull ITimeGraphRowModel>> fetchRowModel(@NonNull SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public @NonNull TmfModelResponse<@NonNull TimeGraphModel> fetchRowModel(@NonNull Map<@NonNull String, @NonNull Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         IGraphWorker graphWorker = getCurrent();
         if (graphWorker == null) {
             return new TmfModelResponse<>(null, Status.COMPLETED, CommonStatusMessage.COMPLETED);
@@ -173,10 +176,18 @@
             return new TmfModelResponse<>(null, Status.COMPLETED, CommonStatusMessage.COMPLETED);
         }
 
+        // TODO server: Parameters validation should be handle separately. It
+        // can be either in the data provider itself or before calling it. It
+        // will avoid the creation of filters and the content of the map can be
+        // use directly.
+        SelectionTimeQueryFilter filter = FetchParametersUtils.createSelectionTimeQuery(fetchParameters);
+        if (filter == null) {
+            return new TmfModelResponse<>(null, Status.FAILED, CommonStatusMessage.INCORRECT_QUERY_PARAMETERS);
+        }
         Map<@NonNull Integer, @NonNull Predicate<@NonNull Multimap<@NonNull String, @NonNull String>>> predicates = new HashMap<>();
-        if (filter instanceof TimeGraphStateQueryFilter) {
-            TimeGraphStateQueryFilter timeEventFilter = (TimeGraphStateQueryFilter) filter;
-            predicates.putAll(computeRegexPredicate(timeEventFilter));
+        Multimap<@NonNull Integer, @NonNull String> regexesMap = DataProviderParameterUtils.extractRegexFilter(fetchParameters);
+        if (regexesMap != null) {
+            predicates.putAll(computeRegexPredicate(regexesMap));
         }
 
         List<@NonNull ITimeGraphRowModel> rowModels = new ArrayList<>();
@@ -199,7 +210,7 @@
                 rowModels.add(new TimeGraphRowModel(id, filteredStates));
             }
         }
-        return new TmfModelResponse<>(rowModels, Status.COMPLETED, CommonStatusMessage.COMPLETED);
+        return new TmfModelResponse<>(new TimeGraphModel(rowModels), Status.COMPLETED, CommonStatusMessage.COMPLETED);
     }
 
     private static final boolean overlaps(long start, long duration, long[] times) {
@@ -222,12 +233,24 @@
     }
 
     @Override
-    public @NonNull TmfModelResponse<@NonNull List<@NonNull ITimeGraphArrow>> fetchArrows(@NonNull TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public @NonNull TmfModelResponse<@NonNull List<@NonNull ITimeGraphArrow>> fetchArrows(@NonNull Map<@NonNull String, @NonNull Object> fetchParameters, @Nullable IProgressMonitor monitor) {
+        // TODO server: Parameters validation should be handle separately. It
+        // can be either in the data provider itself or before calling it. It
+        // will avoid the creation of filters and the content of the map can be
+        // use directly.
+        TimeQueryFilter filter = FetchParametersUtils.createTimeQuery(fetchParameters);
+        if (filter == null) {
+            return new TmfModelResponse<>(null, Status.FAILED, CommonStatusMessage.INCORRECT_QUERY_PARAMETERS);
+        }
         return new TmfModelResponse<>(getLinkList(filter.getStart(), filter.getEnd()), Status.COMPLETED, CommonStatusMessage.COMPLETED);
     }
 
     @Override
-    public @NonNull TmfModelResponse<@NonNull Map<@NonNull String, @NonNull String>> fetchTooltip(@NonNull SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public @NonNull TmfModelResponse<@NonNull Map<@NonNull String, @NonNull String>> fetchTooltip(@NonNull Map<@NonNull String, @NonNull Object> fetchParameters, @Nullable IProgressMonitor monitor) {
+        SelectionTimeQueryFilter filter = FetchParametersUtils.createSelectionTimeQuery(fetchParameters);
+        if (filter == null) {
+            return new TmfModelResponse<>(null, Status.FAILED, CommonStatusMessage.INCORRECT_QUERY_PARAMETERS);
+        }
         IGraphWorker worker = fWorkerToEntryId.inverse().get(filter.getSelectedItems().iterator().next());
         if (worker == null) {
             return new TmfModelResponse<>(null, Status.COMPLETED, CommonStatusMessage.COMPLETED);
@@ -299,7 +322,7 @@
             // create host entry
             String host = owner.getHostId();
             long parentId = fHostIdToEntryId.computeIfAbsent(host, h -> ATOMIC_LONG.getAndIncrement());
-            fHostEntries.computeIfAbsent(host, h -> new CriticalPathEntry(parentId, -1L, host, fStart, fEnd, sum, percent));
+            fHostEntries.computeIfAbsent(host, h -> new CriticalPathEntry(parentId, -1L, Collections.singletonList(host), fStart, fEnd, sum, percent));
 
             long entryId = fWorkerToEntryId.computeIfAbsent(owner, w -> ATOMIC_LONG.getAndIncrement());
             CriticalPathEntry entry = new CriticalPathEntry(entryId, parentId, owner, fStart, fEnd, sum, percent);
@@ -416,6 +439,46 @@
         return 8;
     }
 
+    @Deprecated
+    @Override
+    public TmfModelResponse<List<CriticalPathEntry>> fetchTree(@NonNull TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        Map<String, Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        TmfModelResponse<@NonNull TmfTreeModel<@NonNull CriticalPathEntry>> response = fetchTree(parameters, monitor);
+        TmfTreeModel<@NonNull CriticalPathEntry> model = response.getModel();
+        List<CriticalPathEntry> treeModel = null;
+        if (model != null) {
+            treeModel = model.getEntries();
+        }
+        return new TmfModelResponse<>(treeModel, response.getStatus(), response.getStatusMessage());
+    }
+
+    @Deprecated
+    @Override
+    public @NonNull TmfModelResponse<@NonNull List<@NonNull ITimeGraphRowModel>> fetchRowModel(@NonNull SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        @NonNull Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.selectionTimeQueryToMap(filter);
+        TmfModelResponse<@NonNull TimeGraphModel> response = fetchRowModel(parameters, monitor);
+        TimeGraphModel model = response.getModel();
+        List<@NonNull ITimeGraphRowModel> rows = null;
+        if (model != null) {
+            rows = model.getRows();
+        }
+        return new TmfModelResponse<>(rows, response.getStatus(), response.getStatusMessage());
+    }
+
+    @Deprecated
+    @Override
+    public @NonNull TmfModelResponse<@NonNull List<@NonNull ITimeGraphArrow>> fetchArrows(@NonNull TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        @NonNull Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        return fetchArrows(parameters, monitor);
+    }
+
+    @Deprecated
+    @Override
+    public @NonNull TmfModelResponse<@NonNull Map<@NonNull String, @NonNull String>> fetchTooltip(@NonNull SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        @NonNull Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.selectionTimeQueryToMap(filter);
+        return fetchTooltip(parameters, monitor);
+    }
+
     @Override
     public @NonNull Multimap<@NonNull String, @NonNull String> getFilterData(long entryId, long time, @Nullable IProgressMonitor monitor) {
         return ITimeGraphStateFilter.mergeMultimaps(ITimeGraphDataProvider.super.getFilterData(entryId, time, monitor),
diff --git a/analysis/org.eclipse.tracecompass.analysis.graph.core/src/org/eclipse/tracecompass/internal/analysis/graph/core/dataprovider/CriticalPathEntry.java b/analysis/org.eclipse.tracecompass.analysis.graph.core/src/org/eclipse/tracecompass/internal/analysis/graph/core/dataprovider/CriticalPathEntry.java
index 5a8bd9b..2ae5b3d 100644
--- a/analysis/org.eclipse.tracecompass.analysis.graph.core/src/org/eclipse/tracecompass/internal/analysis/graph/core/dataprovider/CriticalPathEntry.java
+++ b/analysis/org.eclipse.tracecompass.analysis.graph.core/src/org/eclipse/tracecompass/internal/analysis/graph/core/dataprovider/CriticalPathEntry.java
@@ -9,6 +9,8 @@
 
 package org.eclipse.tracecompass.internal.analysis.graph.core.dataprovider;
 
+import java.util.Collections;
+import java.util.List;
 import java.util.Map.Entry;
 
 import org.eclipse.jdt.annotation.NonNull;
@@ -53,7 +55,7 @@
      */
     public CriticalPathEntry(long id, long parentId, IGraphWorker worker,
             long startTime, long endTime, Long sum, Double percent) {
-        super(id, parentId, String.valueOf(worker), startTime, endTime);
+        super(id, parentId, Collections.singletonList(String.valueOf(worker)), startTime, endTime);
         fSum = sum;
         fPercent = percent;
         fAspects.put("hostId", worker.getHostId());
@@ -69,8 +71,8 @@
      *            unique entry ID
      * @param parentId
      *            entry's parent unique ID
-     * @param name
-     *            The entry name
+     * @param labels
+     *            The entry labels
      * @param startTime
      *            entry's start time
      * @param endTime
@@ -82,9 +84,9 @@
      *            {@link TmfGraphStatistics} percentage for the associated
      *            {@link IGraphWorker}
      */
-    public CriticalPathEntry(long id, long parentId, @NonNull String name,
+    public CriticalPathEntry(long id, long parentId, @NonNull List<@NonNull String> labels,
             long startTime, long endTime, Long sum, Double percent) {
-        super(id, parentId, name, startTime, endTime);
+        super(id, parentId, labels, startTime, endTime);
         fSum = sum;
         fPercent = percent;
     }
diff --git a/analysis/org.eclipse.tracecompass.analysis.graph.ui/src/org/eclipse/tracecompass/internal/analysis/graph/ui/criticalpath/view/CriticalPathPresentationProvider.java b/analysis/org.eclipse.tracecompass.analysis.graph.ui/src/org/eclipse/tracecompass/internal/analysis/graph/ui/criticalpath/view/CriticalPathPresentationProvider.java
index 0db811d..882b65b 100644
--- a/analysis/org.eclipse.tracecompass.analysis.graph.ui/src/org/eclipse/tracecompass/internal/analysis/graph/ui/criticalpath/view/CriticalPathPresentationProvider.java
+++ b/analysis/org.eclipse.tracecompass.analysis.graph.ui/src/org/eclipse/tracecompass/internal/analysis/graph/ui/criticalpath/view/CriticalPathPresentationProvider.java
@@ -17,6 +17,7 @@
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.swt.graphics.RGB;
 import org.eclipse.tracecompass.common.core.NonNullUtils;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphDataProvider;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphEntryModel;
@@ -185,7 +186,7 @@
             long id = ((TimeGraphEntry) entry).getModel().getId();
             ITimeGraphDataProvider<? extends TimeGraphEntryModel> provider = BaseDataProviderTimeGraphView.getProvider((TimeGraphEntry) entry);
             SelectionTimeQueryFilter filter = new SelectionTimeQueryFilter(Collections.singletonList(hoverTime), Collections.singleton(id));
-            TmfModelResponse<@NonNull Map<@NonNull String, @NonNull String>> tooltipResponse = provider.fetchTooltip(filter, null);
+            TmfModelResponse<@NonNull Map<@NonNull String, @NonNull String>> tooltipResponse = provider.fetchTooltip(FetchParametersUtils.selectionTimeQueryToMap(filter), null);
             Map<@NonNull String, @NonNull String> tooltipModel = tooltipResponse.getModel();
             if (tooltipModel != null) {
                 eventHoverToolTipInfo.putAll(tooltipModel);
diff --git a/analysis/org.eclipse.tracecompass.analysis.graph.ui/src/org/eclipse/tracecompass/internal/analysis/graph/ui/criticalpath/view/CriticalPathView.java b/analysis/org.eclipse.tracecompass.analysis.graph.ui/src/org/eclipse/tracecompass/internal/analysis/graph/ui/criticalpath/view/CriticalPathView.java
index 93f4a5b..dda4410 100644
--- a/analysis/org.eclipse.tracecompass.analysis.graph.ui/src/org/eclipse/tracecompass/internal/analysis/graph/ui/criticalpath/view/CriticalPathView.java
+++ b/analysis/org.eclipse.tracecompass.analysis.graph.ui/src/org/eclipse/tracecompass/internal/analysis/graph/ui/criticalpath/view/CriticalPathView.java
@@ -25,6 +25,7 @@
 import org.eclipse.tracecompass.analysis.graph.core.criticalpath.CriticalPathModule;
 import org.eclipse.tracecompass.internal.analysis.graph.core.dataprovider.CriticalPathDataProvider;
 import org.eclipse.tracecompass.internal.analysis.graph.core.dataprovider.CriticalPathEntry;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphArrow;
@@ -162,7 +163,7 @@
         for (Map.Entry<ITimeGraphDataProvider<?>, Map<Long, TimeGraphEntry>> entry : table.rowMap().entrySet()) {
             ITimeGraphDataProvider<?> provider = entry.getKey();
             Map<Long, TimeGraphEntry> map = entry.getValue();
-            TmfModelResponse<List<ITimeGraphArrow>> response = provider.fetchArrows(queryFilter, monitor);
+            TmfModelResponse<List<ITimeGraphArrow>> response = provider.fetchArrows(FetchParametersUtils.timeQueryToMap(queryFilter), monitor);
             List<ITimeGraphArrow> model = response.getModel();
 
             if (monitor.isCanceled()) {
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core.tests/src/org/eclipse/tracecompass/analysis/os/linux/core/tests/cpuusage/CpuUsageDataProviderTest.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core.tests/src/org/eclipse/tracecompass/analysis/os/linux/core/tests/cpuusage/CpuUsageDataProviderTest.java
index ff5a489..92d5873 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core.tests/src/org/eclipse/tracecompass/analysis/os/linux/core/tests/cpuusage/CpuUsageDataProviderTest.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core.tests/src/org/eclipse/tracecompass/analysis/os/linux/core/tests/cpuusage/CpuUsageDataProviderTest.java
@@ -15,6 +15,7 @@
 import static org.junit.Assert.fail;
 
 import java.io.File;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -33,12 +34,14 @@
 import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelTrace;
 import org.eclipse.tracecompass.internal.analysis.os.linux.core.cpuusage.CpuUsageDataProvider;
 import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
+import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
 import org.eclipse.tracecompass.tmf.core.event.TmfEvent;
 import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectedCpuQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
-import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.response.ITmfResponse.Status;
+import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTrace;
@@ -124,7 +127,7 @@
 
     /**
      * Test the
-     * {@link CpuUsageDataProvider#fetchTree(TimeQueryFilter, IProgressMonitor)}
+     * {@link CpuUsageDataProvider#fetchTree(Map, IProgressMonitor)}
      * method.
      * <p>
 
@@ -136,11 +139,16 @@
 
         /* This range should query the total range */
         TimeQueryFilter filter = new SelectedCpuQueryFilter(0L, 30L, 2, Collections.emptyList(), Collections.emptySet());
-        TmfModelResponse<List<CpuUsageEntryModel>> response = dataProvider.fetchTree(filter, monitor);
+        @NonNull Map<@NonNull String, @NonNull Object> parameters = new HashMap<>();
+        parameters.put(DataProviderParameterUtils.REQUESTED_TIME_KEY, getTimeRequested(filter));
+        parameters.put(DataProviderParameterUtils.REQUESTED_ITEMS_KEY, Collections.emptyList());
+        parameters.put("cpus", Collections.emptySet());
+        TmfModelResponse<@NonNull TmfTreeModel<@NonNull CpuUsageEntryModel>> response = dataProvider.fetchTree(parameters, monitor);
 
         assertTrue(response.getStatus() == Status.COMPLETED);
 
-        List<CpuUsageEntryModel> model = response.getModel();
+        TmfTreeModel<@NonNull CpuUsageEntryModel> model = response.getModel();
+        assertNotNull(model);
         /* Maps a tid to the total time */
         Map<Integer, Long> expected = new HashMap<>();
         expected.put(1, 5L);
@@ -148,48 +156,54 @@
         expected.put(3, 11L);
         expected.put(4, 13L);
         expected.put(-2, 48L);
-        compareModel(expected, model);
+        compareModel(expected, model.getEntries());
 
         /* Verify a range when a process runs at the start */
         filter = new SelectedCpuQueryFilter(22L, 25L, 2, Collections.emptyList(), Collections.emptySet());
-        response = dataProvider.fetchTree(filter, monitor);
+        parameters.put(DataProviderParameterUtils.REQUESTED_TIME_KEY, getTimeRequested(filter));
+        response = dataProvider.fetchTree(parameters, monitor);
         assertTrue(response.getStatus() == Status.COMPLETED);
 
         model = response.getModel();
+        assertNotNull(model);
         /* Maps a tid to the total time */
         expected.clear();
         expected.put(3, 3L);
         expected.put(4, 3L);
         expected.put(-2, 6L);
-        compareModel(expected, model);
+        compareModel(expected, model.getEntries());
 
         /* Verify a range when a process runs at the end */
         filter = new SelectedCpuQueryFilter(1L, 4L, 2, Collections.emptyList(), Collections.emptySet());
-        response = dataProvider.fetchTree(filter, monitor);
+        parameters.put(DataProviderParameterUtils.REQUESTED_TIME_KEY, getTimeRequested(filter));
+        response = dataProvider.fetchTree(parameters, monitor);
         assertTrue(response.getStatus() == Status.COMPLETED);
 
         model = response.getModel();
+        assertNotNull(model);
         /* Maps a tid to the total time */
         expected.clear();
         expected.put(2, 3L);
         expected.put(3, 1L);
         expected.put(4, 2L);
         expected.put(-2, 6L);
-        compareModel(expected, model);
+        compareModel(expected, model.getEntries());
 
         /* Verify a range when a process runs at start and at the end */
         filter = new SelectedCpuQueryFilter(4L, 13L, 2, Collections.emptyList(), Collections.emptySet());
-        response = dataProvider.fetchTree(filter, monitor);
+        parameters.put(DataProviderParameterUtils.REQUESTED_TIME_KEY, getTimeRequested(filter));
+        response = dataProvider.fetchTree(parameters, monitor);
         assertTrue(response.getStatus() == Status.COMPLETED);
 
         model = response.getModel();
+        assertNotNull(model);
         /* Maps a tid to the total time */
         expected.clear();
         expected.put(2, 9L);
         expected.put(3, 5L);
         expected.put(4, 4L);
         expected.put(-2, 18L);
-        compareModel(expected, model);
+        compareModel(expected, model.getEntries());
 
     }
 
@@ -200,4 +214,12 @@
         assertEquals("model entries", expected, actual);
     }
 
+    private static @NonNull List<Long> getTimeRequested(TimeQueryFilter filter) {
+        List<Long> times = new ArrayList<>();
+        for (long time : filter.getTimesRequested()) {
+            times.add(time);
+        }
+        return times;
+    }
+
 }
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core.tests/src/org/eclipse/tracecompass/analysis/os/linux/core/tests/inputoutput/InputOutputDataProviderTest.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core.tests/src/org/eclipse/tracecompass/analysis/os/linux/core/tests/inputoutput/InputOutputDataProviderTest.java
index 915ad45..6164e56 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core.tests/src/org/eclipse/tracecompass/analysis/os/linux/core/tests/inputoutput/InputOutputDataProviderTest.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core.tests/src/org/eclipse/tracecompass/analysis/os/linux/core/tests/inputoutput/InputOutputDataProviderTest.java
@@ -15,7 +15,6 @@
 
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.List;
 import java.util.Map;
 
 import org.eclipse.core.runtime.IProgressMonitor;
@@ -26,8 +25,8 @@
 import org.eclipse.tracecompass.analysis.os.linux.core.tests.stubs.inputoutput.IoTestCase.DiskActivity;
 import org.eclipse.tracecompass.analysis.os.linux.core.tests.stubs.inputoutput.IoTestFactory;
 import org.eclipse.tracecompass.internal.analysis.os.linux.core.inputoutput.DisksIODataProvider;
-import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeDataModel;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.model.xy.ISeriesModel;
 import org.eclipse.tracecompass.tmf.core.model.xy.ITmfXyModel;
 import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
@@ -104,13 +103,13 @@
         DisksIODataProvider provider = getProvider();
         Collection<@NonNull DiskActivity> diskActivity = fTestCase.getDiskActivity();
         for (DiskActivity test : diskActivity) {
-            TimeQueryFilter filter = test.getTimeQuery();
-            TmfModelResponse<@NonNull List<@NonNull TmfTreeDataModel>> response = provider.fetchTree(filter, PROGRESS_MONITOR);
+            Map<@NonNull String, @NonNull Object> parameters = test.getTimeQuery();
+            TmfModelResponse<@NonNull TmfTreeModel<@NonNull TmfTreeDataModel>> response = provider.fetchTree(parameters, PROGRESS_MONITOR);
             assertEquals(ITmfResponse.Status.COMPLETED, response.getStatus());
-            List<@NonNull TmfTreeDataModel> model = response.getModel();
+            TmfTreeModel<@NonNull TmfTreeDataModel> model = response.getModel();
             assertNotNull(model);
-            filter = test.getTimeQueryForModel(model);
-            TmfModelResponse<@NonNull ITmfXyModel> yResponse = provider.fetchXY(filter, PROGRESS_MONITOR);
+            parameters = test.getTimeQueryForModel(model);
+            TmfModelResponse<@NonNull ITmfXyModel> yResponse = provider.fetchXY(parameters, PROGRESS_MONITOR);
             assertEquals(ITmfResponse.Status.COMPLETED, yResponse.getStatus());
             ITmfXyModel yModel = yResponse.getModel();
             assertNotNull(yModel);
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core.tests/src/org/eclipse/tracecompass/analysis/os/linux/core/tests/kernel/ThreadStatusDataProviderTest.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core.tests/src/org/eclipse/tracecompass/analysis/os/linux/core/tests/kernel/ThreadStatusDataProviderTest.java
index dcc7a34..d93c8ff 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core.tests/src/org/eclipse/tracecompass/analysis/os/linux/core/tests/kernel/ThreadStatusDataProviderTest.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core.tests/src/org/eclipse/tracecompass/analysis/os/linux/core/tests/kernel/ThreadStatusDataProviderTest.java
@@ -28,6 +28,7 @@
 import org.eclipse.tracecompass.analysis.os.linux.core.tests.stubs.trace.TmfXmlKernelTraceStub;
 import org.eclipse.tracecompass.internal.analysis.os.linux.core.threadstatus.ThreadEntryModel;
 import org.eclipse.tracecompass.internal.analysis.os.linux.core.threadstatus.ThreadStatusDataProvider;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.tmf.core.event.TmfEvent;
 import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
@@ -35,6 +36,8 @@
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphArrow;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphRowModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphState;
+import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphModel;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
@@ -83,18 +86,19 @@
     }
 
     private static Map<Long, String> assertAndGetTree(ThreadStatusDataProvider provider) throws IOException {
-        TmfModelResponse<List<ThreadEntryModel>> treeResponse = provider.fetchTree(new TimeQueryFilter(0, Long.MAX_VALUE, 2), null);
+        TmfModelResponse<TmfTreeModel<@NonNull ThreadEntryModel>> treeResponse = provider.fetchTree(FetchParametersUtils.timeQueryToMap(new TimeQueryFilter(0, Long.MAX_VALUE, 2)), null);
         assertNotNull(treeResponse);
         assertEquals(ITmfResponse.Status.COMPLETED, treeResponse.getStatus());
-        List<ThreadEntryModel> treeModel = treeResponse.getModel();
+        TmfTreeModel<@NonNull ThreadEntryModel> treeModel = treeResponse.getModel();
         assertNotNull(treeModel);
+        List<@NonNull ThreadEntryModel> treeEntries = treeModel.getEntries();
 
         List<String> expectedStrings = Files.readAllLines(Paths.get("testfiles/kernel_analysis/expectedThreadStatusTree"));
-        assertEquals(expectedStrings.size(), treeModel.size());
+        assertEquals(expectedStrings.size(), treeEntries.size());
         for (int i = 0; i < expectedStrings.size(); i++) {
             String expectedString = expectedStrings.get(i);
             String[] split = expectedString.split(",");
-            ThreadEntryModel threadEntry = treeModel.get(i);
+            ThreadEntryModel threadEntry = treeEntries.get(i);
 
             assertEquals(split[0], threadEntry.getName());
             assertEquals(Long.parseLong(split[1]), threadEntry.getStartTime());
@@ -103,27 +107,28 @@
             assertEquals(Integer.parseInt(split[4]), threadEntry.getParentThreadId());
         }
         Map<Long, String> map = new HashMap<>();
-        for (ThreadEntryModel threadModel : treeModel) {
+        for (ThreadEntryModel threadModel : treeEntries) {
             map.put(threadModel.getId(), threadModel.getName());
         }
         return map;
     }
 
     private static void assertRows(ThreadStatusDataProvider provider, Map<Long, String> idsToNames) throws IOException {
-        TmfModelResponse<List<ITimeGraphRowModel>> rowResponse = provider.fetchRowModel(new SelectionTimeQueryFilter(1, 80, 80, idsToNames.keySet()), null);
+        TmfModelResponse<TimeGraphModel> rowResponse = provider.fetchRowModel(FetchParametersUtils.selectionTimeQueryToMap(new SelectionTimeQueryFilter(1, 80, 80, idsToNames.keySet())), null);
         assertNotNull(rowResponse);
         assertEquals(ITmfResponse.Status.COMPLETED, rowResponse.getStatus());
-        List<ITimeGraphRowModel> rowModel = rowResponse.getModel();
+        TimeGraphModel rowModel = rowResponse.getModel();
         assertNotNull(rowModel);
+        List<@NonNull ITimeGraphRowModel> rows = rowModel.getRows();
         // ensure row order
-        rowModel.sort(Comparator.comparingLong(ITimeGraphRowModel::getEntryID));
+        rows.sort(Comparator.comparingLong(ITimeGraphRowModel::getEntryID));
 
         List<String> expectedStrings = Files.readAllLines(Paths.get("testfiles/kernel_analysis/expectedThreadStatusRows"));
-        assertEquals(expectedStrings.size(), rowModel.size());
+        assertEquals(expectedStrings.size(), rows.size());
         for (int i = 0; i < expectedStrings.size(); i++) {
             String expectedString = expectedStrings.get(i);
             String[] split = expectedString.split(":");
-            ITimeGraphRowModel row = rowModel.get(i);
+            ITimeGraphRowModel row = rows.get(i);
 
             assertEquals(split[0], idsToNames.get(row.getEntryID()));
 
@@ -143,7 +148,7 @@
     }
 
     private static void assertArrows(ThreadStatusDataProvider provider, Map<Long, String> idsToNames) throws IOException {
-        TmfModelResponse<List<ITimeGraphArrow>> arrowResponse = provider.fetchArrows(new TimeQueryFilter(1, 80, 80), null);
+        TmfModelResponse<List<ITimeGraphArrow>> arrowResponse = provider.fetchArrows(FetchParametersUtils.timeQueryToMap(new TimeQueryFilter(1, 80, 80)), null);
         assertNotNull(arrowResponse);
         assertEquals(ITmfResponse.Status.COMPLETED, arrowResponse.getStatus());
         List<ITimeGraphArrow> arrows = arrowResponse.getModel();
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core.tests/stubs/org/eclipse/tracecompass/analysis/os/linux/core/tests/stubs/inputoutput/IoTestCase.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core.tests/stubs/org/eclipse/tracecompass/analysis/os/linux/core/tests/stubs/inputoutput/IoTestCase.java
index 79bc595..2ed8604 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core.tests/stubs/org/eclipse/tracecompass/analysis/os/linux/core/tests/stubs/inputoutput/IoTestCase.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core.tests/stubs/org/eclipse/tracecompass/analysis/os/linux/core/tests/stubs/inputoutput/IoTestCase.java
@@ -8,17 +8,20 @@
  *******************************************************************************/
 package org.eclipse.tracecompass.analysis.os.linux.core.tests.stubs.inputoutput;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
 
 import org.eclipse.tracecompass.analysis.os.linux.core.inputoutput.IoOperationType;
 import org.eclipse.tracecompass.analysis.os.linux.core.tests.stubs.LinuxTestCase;
-import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
+import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeDataModel;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Multimap;
@@ -187,10 +190,13 @@
         /**
          * Get the time query given the test parameters
          *
-         * @return The time query filter
+         * @return The parameter map for the time query
          */
-        public TimeQueryFilter getTimeQuery() {
-            return new TimeQueryFilter(fStartTime, fEndTime, fResolution);
+        public Map<String, Object> getTimeQuery() {
+            TimeQueryFilter filter = new TimeQueryFilter(fStartTime, fEndTime, fResolution);
+            Map<String, Object> parameters = new HashMap<>();
+            parameters.put(DataProviderParameterUtils.REQUESTED_TIME_KEY, getTimeRequested(filter));
+            return parameters;
         }
 
         /**
@@ -201,10 +207,10 @@
          *            The list of tree models available
          * @return The query
          */
-        public TimeQueryFilter getTimeQueryForModel(List<TmfTreeDataModel> model) {
+        public Map<String, Object> getTimeQueryForModel(TmfTreeModel<TmfTreeDataModel> model) {
             long diskId = getDiskId(model);
             long selectionId = -1;
-            for (TmfTreeDataModel oneModel : model) {
+            for (TmfTreeDataModel oneModel : model.getEntries()) {
                 if (oneModel.getParentId() == diskId) {
                     switch (fType) {
                     case READ:
@@ -226,11 +232,13 @@
             if (selectionId == -1) {
                 throw new NoSuchElementException("Requested entry not found for " + fDiskName + ' ' + fType);
             }
-            return new SelectionTimeQueryFilter(fStartTime, fEndTime, fResolution, Collections.singleton(selectionId));
+            Map<String, Object> parameters = getTimeQuery();
+            parameters.put(DataProviderParameterUtils.REQUESTED_ITEMS_KEY, Collections.singletonList(selectionId));
+            return parameters;
         }
 
-        private long getDiskId(List<TmfTreeDataModel> model) {
-            for (TmfTreeDataModel oneModel : model) {
+        private long getDiskId(TmfTreeModel<TmfTreeDataModel> model) {
+            for (TmfTreeDataModel oneModel : model.getEntries()) {
                 if (fDiskName.equals(oneModel.getName())) {
                     return oneModel.getId();
                 }
@@ -280,4 +288,12 @@
         return Collections.emptyList();
     }
 
+    private static List<Long> getTimeRequested(TimeQueryFilter filter) {
+        List<Long> times = new ArrayList<>();
+        for (long time : filter.getTimesRequested()) {
+            times.add(time);
+        }
+        return times;
+    }
+
 }
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/cpuusage/CpuUsageEntryModel.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/cpuusage/CpuUsageEntryModel.java
index c55da01..2038eba 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/cpuusage/CpuUsageEntryModel.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/cpuusage/CpuUsageEntryModel.java
@@ -9,6 +9,8 @@
 
 package org.eclipse.tracecompass.analysis.os.linux.core.cpuusage;
 
+import java.util.Collections;
+import java.util.List;
 import java.util.Objects;
 
 import org.eclipse.jdt.annotation.Nullable;
@@ -40,7 +42,26 @@
      *            The total amount of time spent on CPU
      */
     public CpuUsageEntryModel(long id, long parentId, String processName, int tid, long time) {
-        super(id, parentId, processName);
+        this(id, parentId, Collections.singletonList(processName), tid, time);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param id
+     *            the new entry's unique ID
+     * @param parentId
+     *            the entry's parent ID
+     * @param tid
+     *            The TID of the process
+     * @param labels
+     *            The process's labels
+     * @param time
+     *            The total amount of time spent on CPU
+     * @since 4.0
+     */
+    public CpuUsageEntryModel(long id, long parentId, List<String> labels, int tid, long time) {
+        super(id, parentId, labels);
         fTid = tid;
         fTime = time;
     }
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/memory/MemoryUsageTreeModel.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/memory/MemoryUsageTreeModel.java
index fded6cf..98cdab2 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/memory/MemoryUsageTreeModel.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/memory/MemoryUsageTreeModel.java
@@ -9,6 +9,8 @@
 
 package org.eclipse.tracecompass.analysis.os.linux.core.memory;
 
+import java.util.Collections;
+import java.util.List;
 import java.util.Objects;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -44,7 +46,24 @@
      *            The thread's name
      */
     public MemoryUsageTreeModel(long id, long parentId, int tid, String name) {
-        super(id, parentId, name);
+        this(id, parentId, tid, Collections.singletonList(name));
+    }
+
+    /**
+     * Constructor
+     *
+     * @param id
+     *            The id of this model
+     * @param parentId
+     *            The parent id of this model
+     * @param tid
+     *            The TID of the process
+     * @param labels
+     *            The thread's labels
+     * @since 4.0
+     */
+    public MemoryUsageTreeModel(long id, long parentId, int tid, List<String> labels) {
+        super(id, parentId, labels);
         fTid = tid;
     }
 
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/cpuusage/CpuUsageDataProvider.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/cpuusage/CpuUsageDataProvider.java
index d9e3426..869d657 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/cpuusage/CpuUsageDataProvider.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/cpuusage/CpuUsageDataProvider.java
@@ -10,6 +10,7 @@
 package org.eclipse.tracecompass.internal.analysis.os.linux.core.cpuusage;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -17,6 +18,7 @@
 import java.util.Map.Entry;
 import java.util.Objects;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.jdt.annotation.Nullable;
@@ -24,13 +26,16 @@
 import org.eclipse.tracecompass.analysis.os.linux.core.cpuusage.KernelCpuUsageAnalysis;
 import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelAnalysisModule;
 import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelThreadInformationProvider;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.internal.tmf.core.model.xy.AbstractTreeCommonXDataProvider;
 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
 import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
+import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
 import org.eclipse.tracecompass.tmf.core.model.YModel;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectedCpuQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.model.xy.IYModel;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
@@ -61,6 +66,11 @@
     public static final String ID = "org.eclipse.tracecompass.analysis.os.linux.core.cpuusage.CpuUsageDataProvider"; //$NON-NLS-1$
 
     /**
+     * Parameter key to extract cpus from the parameters map
+     */
+    public static final String REQUESTED_CPUS_KEY = "requested_cpus"; //$NON-NLS-1$
+
+    /**
      * The Fake Tid to identify the total entry.
      * @since 2.4
      */
@@ -106,9 +116,17 @@
      * @since 2.5
      */
     @Override
-    protected @Nullable Map<String, IYModel> getYModels(ITmfStateSystem ss, SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    protected @Nullable Map<String, IYModel> getYModels(ITmfStateSystem ss, Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         Set<Integer> cpus = Collections.emptySet();
 
+        SelectionTimeQueryFilter filter = createCpuQuery(fetchParameters);
+        if (filter == null) {
+            filter = FetchParametersUtils.createSelectionTimeQuery(fetchParameters);
+            if (filter == null) {
+                return null;
+            }
+        }
+
         if (filter instanceof SelectedCpuQueryFilter) {
             cpus = ((SelectedCpuQueryFilter) filter).getSelectedCpus();
         }
@@ -183,21 +201,22 @@
      * @since 2.5
      */
     @Override
-    protected List<CpuUsageEntryModel> getTree(ITmfStateSystem ss, TimeQueryFilter filter, @Nullable IProgressMonitor monitor)
+    protected TmfTreeModel<CpuUsageEntryModel> getTree(ITmfStateSystem ss, Map<String, Object> parameters, @Nullable IProgressMonitor monitor)
             throws StateSystemDisposedException {
-        if (!(filter instanceof SelectedCpuQueryFilter)) {
-            return Collections.emptyList();
+        TimeQueryFilter filter = FetchParametersUtils.createTimeQuery(parameters);
+        if (filter == null) {
+            return new TmfTreeModel<>(Collections.emptyList(), Collections.emptyList());
         }
 
-        SelectedCpuQueryFilter cpuQueryFilter = (SelectedCpuQueryFilter) filter;
         long end = filter.getEnd();
 
         List<CpuUsageEntryModel> entryList = new ArrayList<>();
-        Map<String, Long> cpuUsageMap = getAnalysisModule().getCpuUsageInRange(cpuQueryFilter.getSelectedCpus(), filter.getStart(), end);
+        Set<Integer> cpus = extractCpuSet(parameters);
+        Map<String, Long> cpuUsageMap = getAnalysisModule().getCpuUsageInRange(cpus, filter.getStart(), end);
 
         long totalTime = cpuUsageMap.getOrDefault(KernelCpuUsageAnalysis.TOTAL, 0l);
         long totalId = getId(ITmfStateSystem.ROOT_ATTRIBUTE);
-        entryList.add(new CpuUsageEntryModel(totalId, -1, getTrace().getName(), TOTAL_SERIES_TID, totalTime));
+        entryList.add(new CpuUsageEntryModel(totalId, -1, Collections.singletonList(getTrace().getName()), TOTAL_SERIES_TID, totalTime));
 
         for (Entry<String, Long> entry : cpuUsageMap.entrySet()) {
             /*
@@ -213,11 +232,11 @@
             if (strings.length > 1) {
                 int tid = Integer.parseInt(strings[1]);
                 if (tid != 0) {
-                    entryList.add(new CpuUsageEntryModel(getId(tid), totalId, getProcessName(tid, strings[1]), tid, entry.getValue()));
+                    entryList.add(new CpuUsageEntryModel(getId(tid), totalId, Collections.singletonList(getProcessName(tid, strings[1])), tid, entry.getValue()));
                 }
             }
         }
-        return entryList;
+        return new TmfTreeModel<>(Collections.emptyList(), entryList);
     }
 
     /*
@@ -241,6 +260,28 @@
         return defaultTidName;
     }
 
+    private static @Nullable SelectedCpuQueryFilter createCpuQuery(Map<String, Object> parameters) {
+        List<Long> timeRequested = DataProviderParameterUtils.extractTimeRequested(parameters);
+        List<Long> selectedItems = DataProviderParameterUtils.extractSelectedItems(parameters);
+        Set<Integer> cpus = extractCpuSet(parameters);
+
+        if (timeRequested == null || selectedItems == null) {
+            return null;
+        }
+
+        return new SelectedCpuQueryFilter(timeRequested, selectedItems, cpus);
+    }
+
+    private static Set<Integer> extractCpuSet(Map<String, Object> parameters) {
+        Object cpus = parameters.get(REQUESTED_CPUS_KEY);
+        if (cpus instanceof Collection<?>) {
+            return ((Collection<?>) cpus).stream().filter(cpu -> cpu instanceof Integer)
+                    .map(cpu -> (Integer) cpu)
+                    .collect(Collectors.toSet());
+        }
+        return Collections.emptySet();
+    }
+
     /**
      * @since 2.4
      */
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/cpuusage/CpuUsageProviderFactory.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/cpuusage/CpuUsageProviderFactory.java
index 8d38e6e..f7a82bf 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/cpuusage/CpuUsageProviderFactory.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/cpuusage/CpuUsageProviderFactory.java
@@ -10,15 +10,25 @@
 package org.eclipse.tracecompass.internal.analysis.os.linux.core.cpuusage;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Objects;
 
+import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.analysis.os.linux.core.cpuusage.KernelCpuUsageAnalysis;
+import org.eclipse.tracecompass.internal.tmf.core.model.DataProviderDescriptor;
 import org.eclipse.tracecompass.internal.tmf.core.model.xy.TmfTreeXYCompositeDataProvider;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor.ProviderType;
 import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderFactory;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataProvider;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
 
 /**
  * Extension point factory for the {@link CpuUsageDataProvider}.
@@ -28,6 +38,15 @@
  */
 public class CpuUsageProviderFactory implements IDataProviderFactory {
 
+    private static final Predicate<? super ITmfTrace> PREDICATE = t -> TmfTraceUtils.getAnalysisModuleOfClass(t, KernelCpuUsageAnalysis.class, KernelCpuUsageAnalysis.ID) != null;
+
+    private static final IDataProviderDescriptor DESCRIPTOR = new DataProviderDescriptor.Builder()
+            .setId(CpuUsageDataProvider.ID)
+            .setName(Objects.requireNonNull(Messages.CpuUsageDataProvider_title))
+            .setDescription(Objects.requireNonNull(Messages.CpuUsageProviderFactory_DescriptionText))
+            .setProviderType(ProviderType.TREE_TIME_XY)
+            .build();
+
     @Override
     public @Nullable ITmfTreeDataProvider<? extends ITmfTreeDataModel> createProvider(ITmfTrace trace) {
         Collection<ITmfTrace> traces = TmfTraceManager.getTraceSet(trace);
@@ -37,4 +56,10 @@
         return TmfTreeXYCompositeDataProvider.create(traces, Objects.requireNonNull(Messages.CpuUsageDataProvider_title), CpuUsageDataProvider.ID);
     }
 
+    @Override
+    public Collection<IDataProviderDescriptor> getDescriptors(@NonNull ITmfTrace trace) {
+        Collection<ITmfTrace> traces = TmfTraceManager.getTraceSet(trace);
+        return Iterables.any(traces, PREDICATE) ? Collections.singletonList(DESCRIPTOR) : Collections.emptyList();
+    }
+
 }
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/cpuusage/Messages.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/cpuusage/Messages.java
index 441b20d..bb0be8d 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/cpuusage/Messages.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/cpuusage/Messages.java
@@ -24,6 +24,10 @@
      * CPU Usage title
      */
     public static @Nullable String CpuUsageDataProvider_title;
+    /**
+     * Data provider help text
+     */
+    public static @Nullable String CpuUsageProviderFactory_DescriptionText;
     static {
         // initialize resource bundle
         NLS.initializeMessages(BUNDLE_NAME, Messages.class);
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/cpuusage/messages.properties b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/cpuusage/messages.properties
index 930208a..4f10897 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/cpuusage/messages.properties
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/cpuusage/messages.properties
@@ -8,3 +8,4 @@
 ###############################################################################
 
 CpuUsageDataProvider_title=CPU Usage
+CpuUsageProviderFactory_DescriptionText=Show the CPU usage of a Linux kernel trace, returns the CPU usage per process and can be filtered by CPU core
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/inputoutput/DisksIODataProvider.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/inputoutput/DisksIODataProvider.java
index 9d6fca8..f61cfd2 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/inputoutput/DisksIODataProvider.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/inputoutput/DisksIODataProvider.java
@@ -21,6 +21,7 @@
 import org.eclipse.tracecompass.analysis.os.linux.core.inputoutput.Attributes;
 import org.eclipse.tracecompass.analysis.os.linux.core.inputoutput.Disk;
 import org.eclipse.tracecompass.analysis.os.linux.core.inputoutput.InputOutputAnalysisModule;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.internal.tmf.core.model.xy.AbstractTreeCommonXDataProvider;
 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
 import org.eclipse.tracecompass.statesystem.core.StateSystemUtils;
@@ -28,8 +29,8 @@
 import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
 import org.eclipse.tracecompass.tmf.core.model.YModel;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
-import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeDataModel;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.model.xy.IYModel;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
@@ -151,10 +152,10 @@
     }
 
     @Override
-    protected List<TmfTreeDataModel> getTree(ITmfStateSystem ss, TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    protected TmfTreeModel<TmfTreeDataModel> getTree(ITmfStateSystem ss, Map<String, Object> parameters, @Nullable IProgressMonitor monitor) {
         List<TmfTreeDataModel> nodes = new ArrayList<>();
         long rootId = getId(ITmfStateSystem.ROOT_ATTRIBUTE);
-        nodes.add(new TmfTreeDataModel(rootId, -1, getTrace().getName()));
+        nodes.add(new TmfTreeDataModel(rootId, -1, Collections.singletonList(getTrace().getName())));
 
         String readName = Objects.requireNonNull(Messages.DisksIODataProvider_read);
         String writeName = Objects.requireNonNull(Messages.DisksIODataProvider_write);
@@ -162,19 +163,19 @@
         for (Integer diskQuark : ss.getQuarks(Attributes.DISKS, "*")) { //$NON-NLS-1$
             String diskName = getDiskName(ss, diskQuark);
             long diskId = getId(diskQuark);
-            nodes.add(new TmfTreeDataModel(diskId, rootId, diskName));
+            nodes.add(new TmfTreeDataModel(diskId, rootId, Collections.singletonList(diskName)));
 
             int readQuark = ss.optQuarkRelative(diskQuark, Attributes.SECTORS_READ);
             if (readQuark != ITmfStateSystem.INVALID_ATTRIBUTE) {
-                nodes.add(new TmfTreeDataModel(getId(readQuark), diskId, readName));
+                nodes.add(new TmfTreeDataModel(getId(readQuark), diskId, Collections.singletonList(readName)));
             }
 
             int writeQuark = ss.optQuarkRelative(diskQuark, Attributes.SECTORS_WRITTEN);
             if (writeQuark != ITmfStateSystem.INVALID_ATTRIBUTE) {
-                nodes.add(new TmfTreeDataModel(getId(writeQuark), diskId, writeName));
+                nodes.add(new TmfTreeDataModel(getId(writeQuark), diskId, Collections.singletonList(writeName)));
             }
         }
-        return nodes;
+        return new TmfTreeModel<>(Collections.emptyList(), nodes);
     }
 
     private static String getDiskName(ITmfStateSystem ss, Integer diskQuark) {
@@ -187,7 +188,11 @@
     }
 
     @Override
-    protected @Nullable Map<String, IYModel> getYModels(ITmfStateSystem ss, SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) throws StateSystemDisposedException {
+    protected @Nullable Map<String, IYModel> getYModels(ITmfStateSystem ss, Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) throws StateSystemDisposedException {
+        SelectionTimeQueryFilter filter = FetchParametersUtils.createSelectionTimeQuery(fetchParameters);
+        if (filter == null) {
+            return null;
+        }
         long[] xValues = filter.getTimesRequested();
         List<DiskBuilder> builders = initBuilders(ss, filter);
         if (builders.isEmpty()) {
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/inputoutput/DisksIODataProviderFactory.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/inputoutput/DisksIODataProviderFactory.java
index 6deb203..12bed6e 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/inputoutput/DisksIODataProviderFactory.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/inputoutput/DisksIODataProviderFactory.java
@@ -10,14 +10,25 @@
 package org.eclipse.tracecompass.internal.analysis.os.linux.core.inputoutput;
 
 import java.util.Collection;
+import java.util.Collections;
+import java.util.Objects;
 
+import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.analysis.os.linux.core.inputoutput.InputOutputAnalysisModule;
+import org.eclipse.tracecompass.internal.tmf.core.model.DataProviderDescriptor;
 import org.eclipse.tracecompass.internal.tmf.core.model.xy.TmfTreeXYCompositeDataProvider;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor.ProviderType;
 import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderFactory;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
 import org.eclipse.tracecompass.tmf.core.model.xy.ITmfTreeXYDataProvider;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
 
 /**
  * Factory to create instances of the {@link ITmfTreeXYDataProvider}. Uses the
@@ -26,6 +37,13 @@
  * @author Loic Prieur-Drevon
  */
 public class DisksIODataProviderFactory implements IDataProviderFactory {
+    private static final Predicate<? super ITmfTrace> PREDICATE = t -> TmfTraceUtils.getAnalysisModuleOfClass(t, InputOutputAnalysisModule.class, InputOutputAnalysisModule.ID) != null;
+    private static final IDataProviderDescriptor DESCRIPTOR = new DataProviderDescriptor.Builder()
+            .setId(DisksIODataProvider.ID)
+            .setName(Objects.requireNonNull(Messages.DisksIODataProvider_title))
+            .setDescription(Objects.requireNonNull(Messages.DisksIODataProviderFactory_descriptionText))
+            .setProviderType(ProviderType.TREE_TIME_XY)
+            .build();
 
     @Override
     public @Nullable ITmfTreeXYDataProvider<? extends ITmfTreeDataModel> createProvider(ITmfTrace trace) {
@@ -36,4 +54,10 @@
         return TmfTreeXYCompositeDataProvider.create(traces, DisksIODataProvider.PROVIDER_TITLE, DisksIODataProvider.ID);
     }
 
+    @Override
+    public Collection<IDataProviderDescriptor> getDescriptors(@NonNull ITmfTrace trace) {
+        Collection<ITmfTrace> traces = TmfTraceManager.getTraceSet(trace);
+        return Iterables.any(traces, PREDICATE) ? Collections.singletonList(DESCRIPTOR) : Collections.emptyList();
+    }
+
 }
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/inputoutput/Messages.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/inputoutput/Messages.java
index ffa1d0b..509eb6e 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/inputoutput/Messages.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/inputoutput/Messages.java
@@ -35,6 +35,11 @@
      */
     public static @Nullable String DisksIODataProvider_write;
 
+    /**
+     * Data provider help text
+     */
+    public static @Nullable String DisksIODataProviderFactory_descriptionText;
+
     static {
         // initialize resource bundle
         NLS.initializeMessages(BUNDLE_NAME, Messages.class);
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/inputoutput/messages.properties b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/inputoutput/messages.properties
index 99a1869..2d9d824 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/inputoutput/messages.properties
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/inputoutput/messages.properties
@@ -9,4 +9,5 @@
 
 DisksIODataProvider_title=Disk I/O View
 DisksIODataProvider_read=read
-DisksIODataProvider_write=write
\ No newline at end of file
+DisksIODataProvider_write=write
+DisksIODataProviderFactory_descriptionText=Show the input and output throughput for each drive on a machine
\ No newline at end of file
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernelmemoryusage/KernelMemoryDataProviderFactory.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernelmemoryusage/KernelMemoryDataProviderFactory.java
index f02d6f7..3979f3c 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernelmemoryusage/KernelMemoryDataProviderFactory.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernelmemoryusage/KernelMemoryDataProviderFactory.java
@@ -10,16 +10,25 @@
 package org.eclipse.tracecompass.internal.analysis.os.linux.core.kernelmemoryusage;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Objects;
 
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.analysis.os.linux.core.kernelmemoryusage.KernelMemoryAnalysisModule;
+import org.eclipse.tracecompass.internal.tmf.core.model.DataProviderDescriptor;
 import org.eclipse.tracecompass.internal.tmf.core.model.xy.TmfTreeXYCompositeDataProvider;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor.ProviderType;
 import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderFactory;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataProvider;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
 
 /**
  * Factory to create instances of the {@link KernelMemoryUsageDataProvider}.
@@ -30,7 +39,14 @@
  */
 public class KernelMemoryDataProviderFactory implements IDataProviderFactory {
 
-    private static final String TITLE = Objects.requireNonNull(Messages.KernelMemoryUsageDataProvider_title);
+    private static final @NonNull String TITLE = Objects.requireNonNull(Messages.KernelMemoryUsageDataProvider_title);
+    private static final Predicate<? super ITmfTrace> PREDICATE = t -> TmfTraceUtils.getAnalysisModuleOfClass(t, KernelMemoryAnalysisModule.class, KernelMemoryAnalysisModule.ID) != null;
+    private static final IDataProviderDescriptor DESCRIPTOR = new DataProviderDescriptor.Builder()
+            .setId(KernelMemoryUsageDataProvider.ID)
+            .setName(TITLE)
+            .setDescription(Objects.requireNonNull(Messages.KernelMemoryDataProviderFactory_descriptionText))
+            .setProviderType(ProviderType.TREE_TIME_XY)
+            .build();
 
     @Override
     public @Nullable ITmfTreeDataProvider<? extends ITmfTreeDataModel> createProvider(@NonNull ITmfTrace trace) {
@@ -42,4 +58,10 @@
         return TmfTreeXYCompositeDataProvider.create(traces, TITLE, KernelMemoryUsageDataProvider.ID);
     }
 
+    @Override
+    public Collection<IDataProviderDescriptor> getDescriptors(@NonNull ITmfTrace trace) {
+        Collection<ITmfTrace> traces = TmfTraceManager.getTraceSet(trace);
+        return Iterables.any(traces, PREDICATE) ? Collections.singletonList(DESCRIPTOR) : Collections.emptyList();
+    }
+
 }
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernelmemoryusage/KernelMemoryUsageDataProvider.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernelmemoryusage/KernelMemoryUsageDataProvider.java
index e0aa819..581ec63 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernelmemoryusage/KernelMemoryUsageDataProvider.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernelmemoryusage/KernelMemoryUsageDataProvider.java
@@ -27,14 +27,16 @@
 import org.eclipse.tracecompass.analysis.os.linux.core.kernelmemoryusage.KernelMemoryAnalysisModule;
 import org.eclipse.tracecompass.analysis.os.linux.core.kernelmemoryusage.KernelMemoryStateProvider;
 import org.eclipse.tracecompass.analysis.os.linux.core.memory.MemoryUsageTreeModel;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.internal.tmf.core.model.xy.AbstractTreeCommonXDataProvider;
 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
 import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
 import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
 import org.eclipse.tracecompass.tmf.core.model.YModel;
-import org.eclipse.tracecompass.tmf.core.model.filters.FilterTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.model.xy.IYModel;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
@@ -104,9 +106,13 @@
      */
     @Override
     protected @Nullable Map<String, IYModel> getYModels(ITmfStateSystem ss,
-            SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor)
+            Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor)
             throws StateSystemDisposedException {
 
+        SelectionTimeQueryFilter filter = FetchParametersUtils.createSelectionTimeQuery(fetchParameters);
+        if (filter == null) {
+            return null;
+        }
         long[] xValues = filter.getTimesRequested();
         long currentEnd = ss.getCurrentEndTime();
 
@@ -229,22 +235,27 @@
      * @since 2.5
      */
     @Override
-    protected List<MemoryUsageTreeModel> getTree(ITmfStateSystem ss,
-            TimeQueryFilter filter, @Nullable IProgressMonitor monitor)
+    protected TmfTreeModel<MemoryUsageTreeModel> getTree(ITmfStateSystem ss,
+            Map<String, Object> parameters, @Nullable IProgressMonitor monitor)
             throws StateSystemDisposedException {
 
+        TimeQueryFilter filter = FetchParametersUtils.createTimeQuery(parameters);
+        if (filter == null) {
+            return new TmfTreeModel<>(Collections.emptyList(), Collections.emptyList());
+        }
         long start = filter.getStart();
         long end = filter.getEnd();
 
         // Let the list of active states be null if we aren't filtering
         List<ITmfStateInterval> active = null;
-        if (filter instanceof FilterTimeQueryFilter && ((FilterTimeQueryFilter) filter).isFiltered()) {
+        Boolean isFiltered = DataProviderParameterUtils.extractIsFiltered(parameters);
+        if (isFiltered != null && isFiltered) {
             if (start == end || start > ss.getCurrentEndTime() || end < ss.getStartTime()) {
                 /*
                  * return an empty list if the filter is empty or does not intersect the state
                  * system
                  */
-                return Collections.emptyList();
+                return new TmfTreeModel<>(Collections.emptyList(), Collections.emptyList());
             }
             active = ss.queryFullState(Long.max(start, ss.getStartTime()));
         }
@@ -253,7 +264,7 @@
         List<Integer> threadQuarkList = ss.getSubAttributes(ITmfStateSystem.ROOT_ATTRIBUTE, false);
 
         long totalId = getId(ITmfStateSystem.ROOT_ATTRIBUTE);
-        nodes.add(new MemoryUsageTreeModel(totalId, -1, TOTAL_TID, getTrace().getName()));
+        nodes.add(new MemoryUsageTreeModel(totalId, -1, TOTAL_TID, Collections.singletonList(getTrace().getName())));
         for (Integer threadQuark : threadQuarkList) {
             if (active == null || active.get(threadQuark).getEndTime() < end) {
                 String tidString = ss.getAttributeName(threadQuark);
@@ -261,10 +272,10 @@
 
                 // Ensure that we reuse the same id for a given quark.
                 long id = getId(threadQuark);
-                nodes.add(new MemoryUsageTreeModel(id, totalId, parseTid(tidString), procname));
+                nodes.add(new MemoryUsageTreeModel(id, totalId, parseTid(tidString), Collections.singletonList(procname)));
             }
         }
-        return nodes;
+        return new TmfTreeModel<>(Collections.emptyList(), nodes);
     }
 
     private static int parseTid(String tidString) {
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernelmemoryusage/Messages.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernelmemoryusage/Messages.java
index 8bd63b0..6ebdaae 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernelmemoryusage/Messages.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernelmemoryusage/Messages.java
@@ -20,6 +20,9 @@
 public class Messages extends NLS {
     private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.analysis.os.linux.core.kernelmemoryusage.messages"; //$NON-NLS-1$
 
+    /** Data Provider help text */
+    public static String KernelMemoryDataProviderFactory_descriptionText;
+
     /**
      * Kernel Memory Usage's title view
      */
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernelmemoryusage/messages.properties b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernelmemoryusage/messages.properties
index 6b942fc..68fe8be 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernelmemoryusage/messages.properties
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernelmemoryusage/messages.properties
@@ -7,5 +7,6 @@
 # http://www.eclipse.org/legal/epl-v10.html
 ###############################################################################
 
+KernelMemoryDataProviderFactory_descriptionText=Show the relative memory usage in the Linux kernel by process, can be filtered to show only the processes which were active on a time range
 KernelMemoryUsageDataProvider_title=Memory Usage
 KernelMemoryUsageDataProvider_Total=Total
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/resourcesstatus/Messages.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/resourcesstatus/Messages.java
index 86afbd8..5ccb982 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/resourcesstatus/Messages.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/resourcesstatus/Messages.java
@@ -18,7 +18,6 @@
  */
 class Messages extends NLS {
     private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.analysis.os.linux.core.resourcesstatus.messages"; //$NON-NLS-1$
-
     /** softirq 0 */
     public static String SoftIrqLabelProvider_softIrq0;
     /** softirq 1 */
@@ -57,6 +56,10 @@
     public static String ResourcesStatusDataProvider_attributeProcessName;
     /** syscall name */
     public static String ResourcesStatusDataProvider_attributeSyscallName;
+    /** Data Provider factory title */
+    public static String ResourcesStatusDataProviderFactory_title;
+    /** Data Provider factory help text */
+    public static String ResourcesStatusDataProviderFactory_descriptionText;
 
     static {
         // initialize resource bundle
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/resourcesstatus/ResourcesEntryModel.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/resourcesstatus/ResourcesEntryModel.java
index 90d9329..39814fc 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/resourcesstatus/ResourcesEntryModel.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/resourcesstatus/ResourcesEntryModel.java
@@ -9,6 +9,8 @@
 
 package org.eclipse.tracecompass.internal.analysis.os.linux.core.resourcesstatus;
 
+import java.util.List;
+
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.tracecompass.analysis.os.linux.core.model.OsStrings;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.IElementResolver;
@@ -52,8 +54,8 @@
      *            unique Entry ID
      * @param parentId
      *            parent ID
-     * @param name
-     *            entry name
+     * @param labels
+     *            entry labels
      * @param startTime
      *            start time for this entry
      * @param endTime
@@ -63,8 +65,8 @@
      * @param type
      *            type of entry (GROUP / CPU / CURRENT_THREAD / IRQ / SOFT_IRQ)
      */
-    public ResourcesEntryModel(long id, long parentId, @NonNull String name, long startTime, long endTime, int resourceId, Type type) {
-        super(id, parentId, name, startTime, endTime, !name.isEmpty());
+    public ResourcesEntryModel(long id, long parentId, @NonNull List<@NonNull String> labels, long startTime, long endTime, int resourceId, Type type) {
+        super(id, parentId, labels, startTime, endTime, !labels.isEmpty());
         fResourceId = resourceId;
         fType = type;
         switch (type) {
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/resourcesstatus/ResourcesEntryModelWeighted.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/resourcesstatus/ResourcesEntryModelWeighted.java
index 2bd3a54..b1a1d65 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/resourcesstatus/ResourcesEntryModelWeighted.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/resourcesstatus/ResourcesEntryModelWeighted.java
@@ -9,6 +9,8 @@
 
 package org.eclipse.tracecompass.internal.analysis.os.linux.core.resourcesstatus;
 
+import java.util.List;
+
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.tracecompass.internal.provisional.tmf.core.model.timegraph.ITimeGraphEntryModelWeighted;
 
@@ -25,8 +27,8 @@
      *            unique Entry ID
      * @param parentId
      *            parent ID
-     * @param name
-     *            entry name
+     * @param labels
+     *            entry labels
      * @param startTime
      *            start time for this entry
      * @param endTime
@@ -40,8 +42,8 @@
      * @param max
      *            The maximum value of the states
      */
-    public ResourcesEntryModelWeighted(long id, long parentId, String name, long startTime, long endTime, int resourceId, Type type, long min, long max) {
-        super(id, parentId, name, startTime, endTime, resourceId, type);
+    public ResourcesEntryModelWeighted(long id, long parentId, List<String> labels, long startTime, long endTime, int resourceId, Type type, long min, long max) {
+        super(id, parentId, labels, startTime, endTime, resourceId, type);
         fMin = min;
         fMax = max;
     }
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/resourcesstatus/ResourcesStatusDataProvider.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/resourcesstatus/ResourcesStatusDataProvider.java
index 00cc2e8..2caa7be 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/resourcesstatus/ResourcesStatusDataProvider.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/resourcesstatus/ResourcesStatusDataProvider.java
@@ -36,19 +36,22 @@
 import org.eclipse.tracecompass.common.core.format.DecimalUnitFormat;
 import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.Attributes;
 import org.eclipse.tracecompass.internal.analysis.os.linux.core.resourcesstatus.ResourcesEntryModel.Type;
-import org.eclipse.tracecompass.internal.tmf.core.model.filters.TimeGraphStateQueryFilter;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.internal.tmf.core.model.timegraph.AbstractTimeGraphDataProvider;
 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
 import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
 import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
 import org.eclipse.tracecompass.tmf.core.model.CommonStatusMessage;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphArrow;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphRowModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphState;
+import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphRowModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphState;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
@@ -132,8 +135,8 @@
     }
 
     @Override
-    protected @NonNull List<@NonNull ResourcesEntryModel> getTree(@NonNull ITmfStateSystem ss,
-            @NonNull TimeQueryFilter filter, @Nullable IProgressMonitor monitor) throws StateSystemDisposedException {
+    protected TmfTreeModel<@NonNull ResourcesEntryModel> getTree(@NonNull ITmfStateSystem ss,
+            Map<String, Object> parameters, @Nullable IProgressMonitor monitor) throws StateSystemDisposedException {
 
         long start = ss.getStartTime();
         long end = ss.getCurrentEndTime();
@@ -141,7 +144,7 @@
         List<@NonNull ResourcesEntryModel> builder = new ArrayList<>();
 
         long traceId = getId(ITmfStateSystem.ROOT_ATTRIBUTE);
-        ResourcesEntryModel resourcesEntryModel = new ResourcesEntryModel(traceId, -1, getTrace().getName(), start, end, -1, Type.GROUP);
+        ResourcesEntryModel resourcesEntryModel = new ResourcesEntryModel(traceId, -1, Collections.singletonList(getTrace().getName()), start, end, -1, Type.GROUP);
         builder.add(resourcesEntryModel);
 
         for (Integer cpuQuark : ss.getQuarks(Attributes.CPUS, WILDCARD)) {
@@ -172,7 +175,7 @@
 
             // Add a separator entry after each CPU entry
             long id = fSeparatorIds.computeIfAbsent(cpu, key -> getEntryId());
-            builder.add(new ResourcesEntryModel(id, traceId, SEPARATOR, start, end, cpu, Type.GROUP));
+            builder.add(new ResourcesEntryModel(id, traceId, Collections.singletonList(SEPARATOR), start, end, cpu, Type.GROUP));
 
             List<Integer> irqQuarks = ss.getQuarks(cpuQuark, Attributes.IRQS, WILDCARD);
             createInterrupt(ss, start, end, cpuEntry, irqQuarks, Type.IRQ, builder);
@@ -181,7 +184,7 @@
             createInterrupt(ss, start, end, cpuEntry, softIrqQuarks, Type.SOFT_IRQ, builder);
         }
 
-        return ImmutableList.copyOf(builder);
+        return new TmfTreeModel<>(Collections.emptyList(), ImmutableList.copyOf(builder));
     }
 
     private static long getCpuFrequency(@NonNull ITmfStateSystem ss, int cpuQuark, @NonNull String freqAttribute) throws StateSystemDisposedException {
@@ -257,34 +260,38 @@
         }
     }
 
-    private static @NonNull String computeEntryName(Type type, int id) {
+    private static @NonNull List<@NonNull String> computeEntryName(Type type, int id) {
         if (type == Type.SOFT_IRQ) {
-            return type.toString() + ' ' + id + ' ' + SoftIrqLabelProvider.getSoftIrq(id);
+            return Collections.singletonList(type.toString() + ' ' + id + ' ' + SoftIrqLabelProvider.getSoftIrq(id));
         } else if (type == Type.CURRENT_THREAD) {
             String threadEntryName = NLS.bind(Messages.ThreadEntry, id);
             if (threadEntryName != null) {
-                return threadEntryName;
+                return Collections.singletonList(threadEntryName);
             }
         } else if (type == Type.CPU) {
             String cpuEntryName = NLS.bind(Messages.CpuEntry, id);
             if (cpuEntryName != null) {
-                return cpuEntryName;
+                return Collections.singletonList(cpuEntryName);
             }
         } else if (type == Type.FREQUENCY) {
             String cpuEntryName = NLS.bind(Messages.FrequencyEntry, id);
             if (cpuEntryName != null) {
-                return cpuEntryName;
+                return Collections.singletonList(cpuEntryName);
             }
         }
-        return type.toString() + ' ' + id;
+        return Collections.singletonList(type.toString() + ' ' + id);
     }
 
     @Override
-    public List<ITimeGraphRowModel> getRowModel(ITmfStateSystem ss, SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor)
+    public TimeGraphModel getRowModel(ITmfStateSystem ss, @NonNull Map<@NonNull String, @NonNull Object> parameters, @Nullable IProgressMonitor monitor)
             throws StateSystemDisposedException {
 
         TreeMultimap<Integer, ITmfStateInterval> intervals = TreeMultimap.create(Comparator.naturalOrder(),
                 Comparator.comparing(ITmfStateInterval::getStartTime));
+        SelectionTimeQueryFilter filter = FetchParametersUtils.createSelectionTimeQuery(parameters);
+        if (filter == null) {
+            return null;
+        }
         Map<@NonNull Long, @NonNull Integer> idsToQuark = getSelectedEntries(filter);
         /* Add the mapping for twin entries as they are not in the parent class BiMap */
         addTwinIrqIds(filter, idsToQuark);
@@ -299,12 +306,12 @@
         }
 
         Map<@NonNull Integer, @NonNull Predicate<@NonNull Multimap<@NonNull String, @NonNull String>>> predicates = new HashMap<>();
-        if (filter instanceof TimeGraphStateQueryFilter) {
-            TimeGraphStateQueryFilter timeEventFilter = (TimeGraphStateQueryFilter) filter;
-            predicates.putAll(computeRegexPredicate(timeEventFilter));
+        Multimap<@NonNull Integer, @NonNull String> regexesMap = DataProviderParameterUtils.extractRegexFilter(parameters);
+        if (regexesMap != null) {
+            predicates.putAll(computeRegexPredicate(regexesMap));
         }
 
-        List<ITimeGraphRowModel> rows = new ArrayList<>();
+        @NonNull List<@NonNull ITimeGraphRowModel> rows = new ArrayList<>();
 
         for (Map.Entry<Long, Integer> idToQuark : idsToQuark.entrySet()) {
             if (monitor != null && monitor.isCanceled()) {
@@ -372,7 +379,7 @@
         synchronized (fExecNamesCache) {
             fExecNamesCache.clear();
         }
-        return rows;
+        return new TimeGraphModel(rows);
     }
 
     /**
@@ -492,8 +499,15 @@
         return list;
     }
 
+    @Deprecated
     @Override
-    public TmfModelResponse<List<ITimeGraphArrow>> fetchArrows(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public @NonNull TmfModelResponse<@NonNull List<@NonNull ITimeGraphArrow>> fetchArrows(@NonNull TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        @NonNull Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        return fetchArrows(parameters, monitor);
+    }
+
+    @Override
+    public @NonNull TmfModelResponse<@NonNull List<@NonNull ITimeGraphArrow>> fetchArrows(@NonNull Map<@NonNull String, @NonNull Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         return new TmfModelResponse<>(null, ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
     }
 
@@ -502,9 +516,20 @@
         return ID;
     }
 
+    @Deprecated
     @Override
-    public TmfModelResponse<Map<String, String>> fetchTooltip(@NonNull SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public @NonNull TmfModelResponse<@NonNull Map<@NonNull String, @NonNull String>> fetchTooltip(@NonNull SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        @NonNull Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.selectionTimeQueryToMap(filter);
+        return fetchTooltip(parameters, monitor);
+    }
+
+    @Override
+    public @NonNull TmfModelResponse<@NonNull Map<@NonNull String, @NonNull String>> fetchTooltip(@NonNull Map<@NonNull String, @NonNull Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         ITmfStateSystem ss = getAnalysisModule().getStateSystem();
+        SelectionTimeQueryFilter filter = FetchParametersUtils.createSelectionTimeQuery(fetchParameters);
+        if (filter == null) {
+            return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, CommonStatusMessage.INCORRECT_QUERY_PARAMETERS);
+        }
         Collection<@NonNull Integer> quarks = getSelectedEntries(filter).values();
 
         boolean isACopy = false;
@@ -676,7 +701,7 @@
         data.putAll(super.getFilterData(entryId, time, monitor));
 
         SelectionTimeQueryFilter filter = new SelectionTimeQueryFilter(Collections.singletonList(time), Collections.singleton(Objects.requireNonNull(entryId)));
-        TmfModelResponse<Map<String, String>> response = fetchTooltip(filter, monitor);
+        TmfModelResponse<Map<String, String>> response = fetchTooltip(FetchParametersUtils.selectionTimeQueryToMap(filter), monitor);
         Map<@NonNull String, @NonNull String> model = response.getModel();
         if (model != null) {
             for (Entry<String, String> entry : model.entrySet()) {
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/resourcesstatus/ResourcesStatusDataProviderFactory.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/resourcesstatus/ResourcesStatusDataProviderFactory.java
index 7571bc4..aed38fd 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/resourcesstatus/ResourcesStatusDataProviderFactory.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/resourcesstatus/ResourcesStatusDataProviderFactory.java
@@ -9,9 +9,16 @@
 
 package org.eclipse.tracecompass.internal.analysis.os.linux.core.resourcesstatus;
 
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Objects;
+
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelAnalysisModule;
+import org.eclipse.tracecompass.internal.tmf.core.model.DataProviderDescriptor;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor.ProviderType;
 import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderFactory;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataProvider;
@@ -26,6 +33,13 @@
  */
 public class ResourcesStatusDataProviderFactory implements IDataProviderFactory {
 
+    private static final IDataProviderDescriptor DESCRIPTOR = new DataProviderDescriptor.Builder()
+            .setId(ResourcesStatusDataProvider.ID)
+            .setName(Objects.requireNonNull(Messages.ResourcesStatusDataProviderFactory_title))
+            .setDescription(Objects.requireNonNull(Messages.ResourcesStatusDataProviderFactory_descriptionText))
+            .setProviderType(ProviderType.TIME_GRAPH)
+            .build();
+
     @Override
     public @Nullable ITmfTreeDataProvider<? extends ITmfTreeDataModel> createProvider(@NonNull ITmfTrace trace) {
         KernelAnalysisModule module = TmfTraceUtils.getAnalysisModuleOfClass(trace, KernelAnalysisModule.class, KernelAnalysisModule.ID);
@@ -37,4 +51,9 @@
         return null;
     }
 
+    @Override
+    public Collection<IDataProviderDescriptor> getDescriptors(@NonNull ITmfTrace trace) {
+        KernelAnalysisModule module = TmfTraceUtils.getAnalysisModuleOfClass(trace, KernelAnalysisModule.class, KernelAnalysisModule.ID);
+        return module != null ? Collections.singletonList(DESCRIPTOR) : Collections.emptyList();
+    }
 }
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/resourcesstatus/messages.properties b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/resourcesstatus/messages.properties
index adbd67d..987163e 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/resourcesstatus/messages.properties
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/resourcesstatus/messages.properties
@@ -10,6 +10,8 @@
 #     Ericsson - Initial API and implementation
 ###############################################################################
 
+ResourcesStatusDataProviderFactory_title=Resources Status
+ResourcesStatusDataProviderFactory_descriptionText=Show the state of CPUs (SYSCALL, RUNNING, IRQ, SOFT_IRQ or IDLE) and its IRQs/SOFT_IRQs as well as its frequency.
 SoftIrqLabelProvider_softIrq0=High priority tasklet
 SoftIrqLabelProvider_softIrq1=Timer
 SoftIrqLabelProvider_softIrq2=Network TX
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/Messages.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/Messages.java
new file mode 100644
index 0000000..49421ee
--- /dev/null
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/Messages.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.analysis.os.linux.core.threadstatus;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Externalized Strings for the {@link ThreadStatusDataProvider} package
+ */
+class Messages extends NLS {
+    private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.analysis.os.linux.core.threadstatus.messages"; //$NON-NLS-1$
+
+    /** The data provider title text */
+    public static String ThreadStatusDataProviderFactory_title;
+    /**
+     * The data provider description text
+     */
+    public static String ThreadStatusDataProviderFactory_descriptionText;
+
+    static {
+        // initialize resource bundle
+        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+    }
+
+    private Messages() {
+    }
+}
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/ThreadEntryModel.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/ThreadEntryModel.java
index 1d5904a..06a06a3 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/ThreadEntryModel.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/ThreadEntryModel.java
@@ -9,6 +9,8 @@
 
 package org.eclipse.tracecompass.internal.analysis.os.linux.core.threadstatus;
 
+import java.util.List;
+
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.tracecompass.analysis.os.linux.core.model.OsStrings;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.IElementResolver;
@@ -31,7 +33,7 @@
      */
     public static final class Builder {
         private final long fId;
-        private @NonNull String fName;
+        private @NonNull List<@NonNull String> fLabels;
         private final long fStartTime;
         private long fEndTime;
         private final int fPid;
@@ -42,8 +44,8 @@
          *
          * @param id
          *            The unique ID for this Entry model for its trace
-         * @param name
-         *            the thread name
+         * @param labels
+         *            the thread labels
          * @param start
          *            the thread's start time
          * @param end
@@ -53,9 +55,9 @@
          * @param ppid
          *            the thread's PPID
          */
-        public Builder(long id, @NonNull String name, long start, long end, int pid, int ppid) {
+        public Builder(long id, @NonNull List<@NonNull String> labels, long start, long end, int pid, int ppid) {
             fId = id;
-            fName = name;
+            fLabels = labels;
             fStartTime = start;
             fEndTime = end;
             fPid = pid;
@@ -104,8 +106,8 @@
          * @param name
          *            the new name
          */
-        public void setName(@NonNull String name) {
-            fName = name;
+        public void setName(@NonNull List<@NonNull String> name) {
+            fLabels = name;
         }
 
         /**
@@ -138,7 +140,7 @@
          *         {@link NullPointerException} if the parent Id is not set.
          */
         public ThreadEntryModel build(long parentId) {
-            return new ThreadEntryModel(fId, parentId, fName, fStartTime, fEndTime, fPid, fPpid);
+            return new ThreadEntryModel(fId, parentId, fLabels, fStartTime, fEndTime, fPid, fPpid);
         }
     }
 
@@ -153,8 +155,8 @@
      *            The unique ID for this Entry model for its trace
      * @param parentId
      *            this Entry model's ID
-     * @param name
-     *            the thread name
+     * @param labels
+     *            the thread labels
      * @param start
      *            the thread's start time
      * @param end
@@ -164,14 +166,14 @@
      * @param ppid
      *            the thread's PPID
      */
-    public ThreadEntryModel(long id, long parentId, @NonNull String name, long start, long end, int pid, int ppid) {
-        super(id, parentId, name, start, end);
+    public ThreadEntryModel(long id, long parentId, @NonNull List<@NonNull String> labels, long start, long end, int pid, int ppid) {
+        super(id, parentId, labels, start, end);
         fThreadId = pid;
         fParentThreadId = ppid;
         fAspects = HashMultimap.create();
         fAspects.put(OsStrings.tid(), String.valueOf(pid));
         fAspects.put(OsStrings.pid(), String.valueOf(ppid));
-        fAspects.put("exec_name", String.valueOf(name));
+        fAspects.put("exec_name", String.valueOf(labels));
     }
 
     /**
@@ -194,7 +196,7 @@
 
     @Override
     public @NonNull String toString() {
-        return "<name=" + getName() + " id=" + getId() + " parentId=" + getParentId() //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        return "<name=" + getLabels() + " id=" + getId() + " parentId=" + getParentId() //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                 + " start=" + getStartTime() + " end=" + getEndTime() //$NON-NLS-1$ //$NON-NLS-2$
                 + " TID=" + fThreadId + " PTID=" + fParentThreadId + ">"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
     }
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/ThreadStatusDataProvider.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/ThreadStatusDataProvider.java
index 14a7ad4..128558b 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/ThreadStatusDataProvider.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/ThreadStatusDataProvider.java
@@ -35,7 +35,7 @@
 import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.Attributes;
 import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.StateValues;
 import org.eclipse.tracecompass.internal.tmf.core.model.AbstractTmfTraceDataProvider;
-import org.eclipse.tracecompass.internal.tmf.core.model.filters.TimeGraphStateQueryFilter;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
 import org.eclipse.tracecompass.statesystem.core.StateSystemUtils.QuarkIterator;
 import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
@@ -43,6 +43,7 @@
 import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
 import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
 import org.eclipse.tracecompass.statesystem.core.interval.TmfStateInterval;
+import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
 import org.eclipse.tracecompass.tmf.core.model.CommonStatusMessage;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
@@ -52,8 +53,10 @@
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphState;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphStateFilter;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphArrow;
+import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphRowModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphState;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
@@ -87,6 +90,12 @@
      */
     public static final @NonNull String CPU = "cpu"; //$NON-NLS-1$
 
+    /**
+     * Parameter key used when the thread tree should be filtered by active
+     * thread
+     */
+    public static final @NonNull String ACTIVE_THREAD_FILTER_KEY = "active_thread_filter"; //$NON-NLS-1$
+
     private static final String WILDCARD = "*"; //$NON-NLS-1$
     private static final Set<Integer> ACTIVE_STATES = ImmutableSet.of(StateValues.PROCESS_STATUS_RUN_USERMODE,
             StateValues.PROCESS_STATUS_RUN_SYSCALL, StateValues.PROCESS_STATUS_INTERRUPTED);
@@ -141,9 +150,9 @@
     }
 
     @Override
-    public TmfModelResponse<List<ThreadEntryModel>> fetchTree(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public @NonNull TmfModelResponse<@NonNull TmfTreeModel<@NonNull ThreadEntryModel>> fetchTree(@NonNull Map<@NonNull String, @NonNull Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         if (fLastEnd == Long.MAX_VALUE) {
-            return new TmfModelResponse<>(filter(fTidToEntry, filter), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
+            return new TmfModelResponse<>(new TmfTreeModel<>(Collections.emptyList(), filter(fTidToEntry, fetchParameters)), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
         }
 
         fModule.waitForInitialization();
@@ -158,7 +167,7 @@
          */
         synchronized (fBuildMap) {
             boolean complete = ss.waitUntilBuilt(0);
-            List<ThreadEntryModel> list = null;
+            @NonNull List<@NonNull ThreadEntryModel> list = Collections.emptyList();
             /* Don't query empty state system */
             if (ss.getNbAttributes() > 0 && ss.getStartTime() != Long.MIN_VALUE) {
                 long end = ss.getCurrentEndTime();
@@ -184,7 +193,7 @@
                 }
 
                 // update the trace Entry.
-                fTidToEntry.replaceValues(Integer.MIN_VALUE, Collections.singleton(new ThreadEntryModel.Builder(fTraceId, getTrace().getName(),
+                fTidToEntry.replaceValues(Integer.MIN_VALUE, Collections.singleton(new ThreadEntryModel.Builder(fTraceId, Collections.singletonList(getTrace().getName()),
                         ss.getStartTime(), end, Integer.MIN_VALUE, Integer.MIN_VALUE)));
 
                 for (Integer threadQuark : ss.getQuarks(Attributes.THREADS, WILDCARD)) {
@@ -209,20 +218,20 @@
 
                 fLastEnd = end;
 
-                list = filter(fTidToEntry, filter);
+                list = filter(fTidToEntry, fetchParameters);
             }
-            if (list != null) {
-                for (ThreadEntryModel model : list) {
-                    fEntryMetadata.put(model.getId(), model.getMetadata());
-                }
+
+            for (ThreadEntryModel model : list) {
+                fEntryMetadata.put(model.getId(), model.getMetadata());
             }
+
             if (complete) {
                 fBuildMap.clear();
                 fLastEnd = Long.MAX_VALUE;
-                return new TmfModelResponse<>(list, ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
+                return new TmfModelResponse<>(new TmfTreeModel<>(Collections.emptyList(), list), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
             }
 
-            return new TmfModelResponse<>(list, ITmfResponse.Status.RUNNING, CommonStatusMessage.RUNNING);
+            return new TmfModelResponse<>(new TmfTreeModel<>(Collections.emptyList(), list), ITmfResponse.Status.RUNNING, CommonStatusMessage.RUNNING);
         }
     }
 
@@ -243,7 +252,7 @@
 
         if (entry == null) {
             long id = fAtomicLong.getAndIncrement();
-            entry = new ThreadEntryModel.Builder(id, execName, startTime, endTime, threadId, ppid);
+            entry = new ThreadEntryModel.Builder(id, Collections.singletonList(execName), startTime, endTime, threadId, ppid);
             fQuarkMap.put(id, threadQuark);
         } else {
             /*
@@ -252,7 +261,7 @@
              */
             entry.setEndTime(endTime);
             entry.setPpid(ppid);
-            entry.setName(execName);
+            entry.setName(Collections.singletonList(execName));
         }
         fBuildMap.put(entryKey, entry);
         fTidToEntry.put(threadId, entry);
@@ -288,9 +297,15 @@
      *            time range to query
      * @return a list of the active threads
      */
-    private List<ThreadEntryModel> filter(TreeMultimap<Integer, ThreadEntryModel.Builder> tidToEntry, TimeQueryFilter filter) {
+    private @NonNull List<@NonNull ThreadEntryModel> filter(TreeMultimap<Integer, ThreadEntryModel.Builder> tidToEntry, @NonNull Map<@NonNull String, @NonNull Object> parameters) {
+        TimeQueryFilter filter = FetchParametersUtils.createTimeQuery(parameters);
+        if (filter == null) {
+            return Collections.emptyList();
+        }
+
         // avoid putting everything as a child of the swapper thread.
-        if (filter.getEnd() == Long.MAX_VALUE) {
+        Boolean isActiveFilter = DataProviderParameterUtils.extractBoolean(parameters, ACTIVE_THREAD_FILTER_KEY);
+        if (isActiveFilter == null || !isActiveFilter) {
             ImmutableList.Builder<ThreadEntryModel> builder = ImmutableList.builder();
             for (ThreadEntryModel.Builder entryBuilder : tidToEntry.values()) {
                 builder.add(build(entryBuilder));
@@ -307,8 +322,9 @@
         if (start > end) {
             return Collections.emptyList();
         }
-        if (filter instanceof SelectionTimeQueryFilter) {
-            Set<Long> cpus = Sets.newHashSet(((SelectionTimeQueryFilter) filter).getSelectedItems());
+        List<@NonNull Long> selectedItems = DataProviderParameterUtils.extractSelectedItems(parameters);
+        if (selectedItems != null) {
+            Set<Long> cpus = Sets.newHashSet(selectedItems);
             List<@NonNull Integer> quarks = ss.getQuarks(Attributes.THREADS, WILDCARD, Attributes.CURRENT_CPU_RQ);
             Set<ThreadEntryModel> models = new HashSet<>();
             Map<Integer, Integer> rqToPidCache = new HashMap<>();
@@ -375,7 +391,7 @@
     }
 
     @Override
-    public TmfModelResponse<List<ITimeGraphRowModel>> fetchRowModel(SelectionTimeQueryFilter filter, IProgressMonitor monitor) {
+    public @NonNull TmfModelResponse<@NonNull TimeGraphModel> fetchRowModel(@NonNull Map<@NonNull String, @NonNull Object> fetchParameters, IProgressMonitor monitor) {
         ITmfStateSystem ss = fModule.getStateSystem();
         if (ss == null) {
             return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, CommonStatusMessage.ANALYSIS_INITIALIZATION_FAILED);
@@ -383,6 +399,7 @@
 
         TreeMultimap<Integer, ITmfStateInterval> intervals = TreeMultimap.create(Comparator.naturalOrder(),
                 Comparator.comparing(ITmfStateInterval::getStartTime));
+        SelectionTimeQueryFilter filter = FetchParametersUtils.createSelectionTimeQuery(fetchParameters);
         Map<Long, Integer> selectedIdsToQuarks = getSelectedIdsToQuarks(filter);
         Collection<Integer> stateAndSyscallQuarks = addSyscall(selectedIdsToQuarks.values(), ss);
         Collection<Long> times = getTimes(ss, filter);
@@ -399,11 +416,12 @@
         }
 
         Map<@NonNull Integer, @NonNull Predicate< @NonNull Multimap<@NonNull String, @NonNull String>>> predicates = new HashMap<>();
-        if (filter instanceof TimeGraphStateQueryFilter) {
-            TimeGraphStateQueryFilter timeEventFilter = (TimeGraphStateQueryFilter) filter;
-            predicates.putAll(computeRegexPredicate(timeEventFilter));
+        Multimap<@NonNull Integer, @NonNull String> regexesMap = DataProviderParameterUtils.extractRegexFilter(fetchParameters);
+        if (regexesMap != null) {
+            predicates.putAll(computeRegexPredicate(regexesMap));
         }
-        List<ITimeGraphRowModel> rows = new ArrayList<>();
+
+        @NonNull List<@NonNull ITimeGraphRowModel> rows = new ArrayList<>();
         for (Entry<Long, Integer> entry : selectedIdsToQuarks.entrySet()) {
             int quark = entry.getValue();
             NavigableSet<ITmfStateInterval> states = intervals.get(quark);
@@ -420,7 +438,7 @@
             });
             rows.add(new TimeGraphRowModel(entry.getKey(), eventList));
         }
-        return new TmfModelResponse<>(rows, ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
+        return new TmfModelResponse<>(new TimeGraphModel(rows), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
     }
 
     private Map<Long, Integer> getSelectedIdsToQuarks(SelectionTimeQueryFilter filter) {
@@ -490,7 +508,7 @@
     }
 
     @Override
-    public TmfModelResponse<List<ITimeGraphArrow>> fetchArrows(TimeQueryFilter filter, IProgressMonitor monitor) {
+    public @NonNull TmfModelResponse<@NonNull List<@NonNull ITimeGraphArrow>> fetchArrows(@NonNull Map<@NonNull String, @NonNull Object> fetchParameters, IProgressMonitor monitor) {
         ITmfStateSystem ss = fModule.getStateSystem();
         if (ss == null) {
             return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, CommonStatusMessage.ANALYSIS_INITIALIZATION_FAILED);
@@ -504,6 +522,7 @@
                 Comparator.naturalOrder(),
                 Comparator.comparing(ITmfStateInterval::getStartTime));
         List<Integer> quarks = ss.getQuarks(Attributes.CPUS, WILDCARD, Attributes.CURRENT_THREAD);
+        TimeQueryFilter filter = FetchParametersUtils.createTimeQuery(fetchParameters);
         Collection<Long> times = getTimes(ss, filter);
         try {
             /* Do the actual query */
@@ -616,7 +635,7 @@
     }
 
     @Override
-    public TmfModelResponse<Map<String, String>> fetchTooltip(@NonNull SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public @NonNull TmfModelResponse<@NonNull Map<@NonNull String, @NonNull String>> fetchTooltip(@NonNull Map<@NonNull String, @NonNull Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         ITmfStateSystem ss = fModule.getStateSystem();
         if (ss == null) {
             return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, CommonStatusMessage.STATE_SYSTEM_FAILED);
@@ -626,6 +645,14 @@
         ITmfResponse.Status status = completed ? ITmfResponse.Status.COMPLETED : ITmfResponse.Status.RUNNING;
         String statusMessage = completed ? CommonStatusMessage.COMPLETED : CommonStatusMessage.RUNNING;
 
+        // TODO server: Parameters validation should be handle separately. It
+        // can be either in the data provider itself or before calling it. It
+        // will avoid the creation of filters and the content of the map can be
+        // use directly.
+        SelectionTimeQueryFilter filter = FetchParametersUtils.createSelectionTimeQuery(fetchParameters);
+        if (filter == null) {
+            return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, CommonStatusMessage.INCORRECT_QUERY_PARAMETERS);
+        }
         Integer quark = fQuarkMap.get(filter.getSelectedItems().iterator().next());
         if (quark == null) {
             return new TmfModelResponse<>(null, status, statusMessage);
@@ -649,6 +676,46 @@
         return new TmfModelResponse<>(null, status, statusMessage);
     }
 
+    @Deprecated
+    @Override
+    public TmfModelResponse<List<ThreadEntryModel>> fetchTree(@NonNull TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        @NonNull Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        TmfModelResponse<@NonNull TmfTreeModel<@NonNull ThreadEntryModel>> response = fetchTree(parameters, monitor);
+        TmfTreeModel<@NonNull ThreadEntryModel> model = response.getModel();
+        List<ThreadEntryModel> treeModel = null;
+        if (model != null) {
+            treeModel = model.getEntries();
+        }
+        return new TmfModelResponse<>(treeModel, response.getStatus(), response.getStatusMessage());
+    }
+
+    @Deprecated
+    @Override
+    public @NonNull TmfModelResponse<@NonNull List<@NonNull ITimeGraphRowModel>> fetchRowModel(@NonNull SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        @NonNull Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.selectionTimeQueryToMap(filter);
+        TmfModelResponse<@NonNull TimeGraphModel> response = fetchRowModel(parameters, monitor);
+        TimeGraphModel model = response.getModel();
+        List<@NonNull ITimeGraphRowModel> rows = null;
+        if (model != null) {
+            rows = model.getRows();
+        }
+        return new TmfModelResponse<>(rows, response.getStatus(), response.getStatusMessage());
+    }
+
+    @Deprecated
+    @Override
+    public @NonNull TmfModelResponse<@NonNull List<@NonNull ITimeGraphArrow>> fetchArrows(@NonNull TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        @NonNull Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        return fetchArrows(parameters, monitor);
+    }
+
+    @Deprecated
+    @Override
+    public @NonNull TmfModelResponse<@NonNull Map<@NonNull String, @NonNull String>> fetchTooltip(@NonNull SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        @NonNull Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.selectionTimeQueryToMap(filter);
+        return fetchTooltip(parameters, monitor);
+    }
+
     @Override
     public @NonNull Multimap<@NonNull String, @NonNull String> getFilterData(long entryId, long time, @Nullable IProgressMonitor monitor) {
         Multimap<@NonNull String, @NonNull String> data = ITimeGraphStateFilter.mergeMultimaps(ITimeGraphDataProvider.super.getFilterData(entryId, time, monitor),
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/ThreadStatusDataProviderFactory.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/ThreadStatusDataProviderFactory.java
index 3fed277..2d37681 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/ThreadStatusDataProviderFactory.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/ThreadStatusDataProviderFactory.java
@@ -9,9 +9,16 @@
 
 package org.eclipse.tracecompass.internal.analysis.os.linux.core.threadstatus;
 
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Objects;
+
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelAnalysisModule;
+import org.eclipse.tracecompass.internal.tmf.core.model.DataProviderDescriptor;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor.ProviderType;
 import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderFactory;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataProvider;
@@ -26,6 +33,13 @@
  */
 public class ThreadStatusDataProviderFactory implements IDataProviderFactory {
 
+    private static final IDataProviderDescriptor DESCRIPTOR = new DataProviderDescriptor.Builder()
+            .setId(ThreadStatusDataProvider.ID)
+            .setName(Objects.requireNonNull(Messages.ThreadStatusDataProviderFactory_title))
+            .setDescription(Objects.requireNonNull(Messages.ThreadStatusDataProviderFactory_descriptionText))
+            .setProviderType(ProviderType.TIME_GRAPH)
+            .build();
+
     @Override
     public @Nullable ITmfTreeDataProvider<? extends ITmfTreeDataModel> createProvider(@NonNull ITmfTrace trace) {
         KernelAnalysisModule module = TmfTraceUtils.getAnalysisModuleOfClass(trace, KernelAnalysisModule.class, KernelAnalysisModule.ID);
@@ -37,4 +51,10 @@
         return null;
     }
 
+    @Override
+    public Collection<IDataProviderDescriptor> getDescriptors(@NonNull ITmfTrace trace) {
+        KernelAnalysisModule module = TmfTraceUtils.getAnalysisModuleOfClass(trace, KernelAnalysisModule.class, KernelAnalysisModule.ID);
+        return module != null ? Collections.singletonList(DESCRIPTOR) : Collections.emptyList();
+    }
+
 }
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/messages.properties b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/messages.properties
new file mode 100644
index 0000000..199ce2d
--- /dev/null
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/threadstatus/messages.properties
@@ -0,0 +1,11 @@
+###############################################################################
+# Copyright (c) 2018 Ericsson
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+ThreadStatusDataProviderFactory_title=Thread Status
+ThreadStatusDataProviderFactory_descriptionText=Show the hierarchy of Linux threads and their status (RUNNING, SYSCALL, IRQ, IDLE)
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/ControlFlowCheckActiveProvider.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/ControlFlowCheckActiveProvider.java
index 4e90a78..1b38c22 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/ControlFlowCheckActiveProvider.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/ControlFlowCheckActiveProvider.java
@@ -13,16 +13,19 @@
 package org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.controlflow;
 
 import java.util.Collections;
-import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.tracecompass.internal.analysis.os.linux.core.threadstatus.ThreadEntryModel;
 import org.eclipse.tracecompass.internal.analysis.os.linux.core.threadstatus.ThreadStatusDataProvider;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphDataProvider;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphEntryModel;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceContext;
@@ -31,9 +34,6 @@
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs.ITimeGraphEntryActiveProvider;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
 
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
-
 /**
  * Provides Functionality for check Active / uncheck inactive
  *
@@ -97,14 +97,16 @@
             return fActive;
         }
         TimeQueryFilter filter = new TimeQueryFilter(range.getStartTime().toNanos(), range.getEndTime().toNanos(), 2);
-        TmfModelResponse<List<ThreadEntryModel>> response = ((ThreadStatusDataProvider) dataProvider).fetchTree(filter, null);
-        List<ThreadEntryModel> model = response.getModel();
+        Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        parameters.put(ThreadStatusDataProvider.ACTIVE_THREAD_FILTER_KEY, true);
+        TmfModelResponse<TmfTreeModel<@NonNull ThreadEntryModel>> response = ((ThreadStatusDataProvider) dataProvider).fetchTree(parameters, null);
+        TmfTreeModel<@NonNull ThreadEntryModel> model = response.getModel();
         if (model == null) {
             // query must have failed, return empty and don't invalidate the cache.
             return Collections.emptySet();
         }
         fRange = range;
-        fActive = Sets.newHashSet(Iterables.transform(model, ThreadEntryModel::getId));
+        fActive = model.getEntries().stream().map(ThreadEntryModel::getId).collect(Collectors.toSet());
         return fActive;
 
     }
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/ControlFlowEntry.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/ControlFlowEntry.java
index 690db99..70b3ae7 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/ControlFlowEntry.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/ControlFlowEntry.java
@@ -13,6 +13,7 @@
 
 package org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.controlflow;
 
+import java.util.Collections;
 import java.util.regex.Pattern;
 
 import org.eclipse.jdt.annotation.NonNull;
@@ -50,7 +51,7 @@
      *            The end time of this process
      */
     public ControlFlowEntry(int quark, @NonNull String execName, int threadId, int parentThreadId, long startTime, long endTime) {
-        this(new ThreadEntryModel(quark, -1, execName, startTime, endTime, threadId, parentThreadId));
+        this(new ThreadEntryModel(quark, -1, Collections.singletonList(execName), startTime, endTime, threadId, parentThreadId));
     }
 
     /**
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/ControlFlowPresentationProvider.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/ControlFlowPresentationProvider.java
index 9a80f86..6ca29f5 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/ControlFlowPresentationProvider.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/ControlFlowPresentationProvider.java
@@ -22,6 +22,7 @@
 import org.eclipse.tracecompass.analysis.os.linux.core.model.ProcessStatus;
 import org.eclipse.tracecompass.internal.analysis.os.linux.ui.Messages;
 import org.eclipse.tracecompass.internal.analysis.os.linux.ui.registry.LinuxStyle;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphDataProvider;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphEntryModel;
@@ -150,7 +151,7 @@
         ControlFlowEntry entry = (ControlFlowEntry) event.getEntry();
         ITimeGraphDataProvider<? extends TimeGraphEntryModel> dataProvider = BaseDataProviderTimeGraphView.getProvider(entry);
         TmfModelResponse<@NonNull Map<@NonNull String, @NonNull String>> response = dataProvider.fetchTooltip(
-                new SelectionTimeQueryFilter(hoverTime, hoverTime, 1, Collections.singletonList(entry.getModel().getId())), null);
+                FetchParametersUtils.selectionTimeQueryToMap(new SelectionTimeQueryFilter(hoverTime, hoverTime, 1, Collections.singletonList(entry.getModel().getId()))), null);
         Map<@NonNull String, @NonNull String> tooltipModel = response.getModel();
         if (tooltipModel != null) {
             retMap.putAll(tooltipModel);
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/ControlFlowView.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/ControlFlowView.java
index ca34bed..dc919a2 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/ControlFlowView.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/ControlFlowView.java
@@ -57,12 +57,15 @@
 import org.eclipse.tracecompass.internal.analysis.os.linux.ui.actions.FollowThreadAction;
 import org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.controlflow.filters.ActiveThreadsFilter;
 import org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.controlflow.filters.DynamicFilterDialog;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderManager;
 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphRowModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphState;
+import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphModel;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
@@ -680,7 +683,7 @@
         boolean complete = false;
         TraceEntry traceEntry = null;
         while (!complete && !monitor.isCanceled()) {
-            TmfModelResponse<List<ThreadEntryModel>> response = dataProvider.fetchTree(new TimeQueryFilter(0, Long.MAX_VALUE, 2), monitor);
+            TmfModelResponse<TmfTreeModel<@NonNull ThreadEntryModel>> response = dataProvider.fetchTree(FetchParametersUtils.timeQueryToMap(new TimeQueryFilter(0, Long.MAX_VALUE, 2)), monitor);
             if (response.getStatus() == ITmfResponse.Status.FAILED) {
                 Activator.getDefault().logError("Thread Status Data Provider failed: " + response.getStatusMessage()); //$NON-NLS-1$
                 return;
@@ -689,10 +692,10 @@
             }
             complete = response.getStatus() == ITmfResponse.Status.COMPLETED;
 
-            List<ThreadEntryModel> model = response.getModel();
-            if (model != null) {
+            TmfTreeModel<@NonNull ThreadEntryModel> model = response.getModel();
+            if (model != null && !model.getEntries().isEmpty()) {
                 synchronized (fEntries) {
-                    for (ThreadEntryModel entry : model) {
+                    for (ThreadEntryModel entry : model.getEntries()) {
                         if (entry.getThreadId() != Integer.MIN_VALUE) {
                             if (traceEntry == null) {
                                 break;
@@ -796,12 +799,12 @@
             Map<Long, TimeGraphEntry> map = Maps.uniqueIndex(unfiltered, e -> e.getModel().getId());
             // use time -1 as a lower bound for the end of Time events to be included.
             SelectionTimeQueryFilter filter = new SelectionTimeQueryFilter(time - 1, time, 2, map.keySet());
-            TmfModelResponse<@NonNull List<@NonNull ITimeGraphRowModel>> response = traceEntry.getProvider().fetchRowModel(filter, null);
-            List<@NonNull ITimeGraphRowModel> model = response.getModel();
+            TmfModelResponse<@NonNull TimeGraphModel> response = traceEntry.getProvider().fetchRowModel(FetchParametersUtils.selectionTimeQueryToMap(filter), null);
+            TimeGraphModel model = response.getModel();
             if (model == null) {
                 continue;
             }
-            for (ITimeGraphRowModel row : model) {
+            for (ITimeGraphRowModel row : model.getRows()) {
                 if (syncToRow(row, time, map)) {
                     return;
                 }
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/filters/ActiveThreadsFilter.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/filters/ActiveThreadsFilter.java
index 4350987..8380739 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/filters/ActiveThreadsFilter.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/controlflow/filters/ActiveThreadsFilter.java
@@ -24,9 +24,11 @@
 import org.eclipse.tracecompass.internal.analysis.os.linux.core.threadstatus.ThreadEntryModel;
 import org.eclipse.tracecompass.internal.analysis.os.linux.core.threadstatus.ThreadStatusDataProvider;
 import org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.controlflow.ControlFlowEntry;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderManager;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
@@ -164,20 +166,23 @@
         long beginTS = winRange.getStartTime().getValue();
         long endTS = winRange.getEndTime().getValue();
 
-        Set<Long> cpus = new HashSet<>();
+        @NonNull Set<@NonNull Long> cpus = new HashSet<>();
         for (Range<Long> range : cpuRanges) {
             for (long cpu = range.lowerEndpoint(); cpu <= range.upperEndpoint(); cpu ++) {
                 cpus.add(cpu);
             }
         }
         TimeQueryFilter filter = new SelectionTimeQueryFilter(beginTS, endTS, 2, cpus);
-        TmfModelResponse<List<ThreadEntryModel>> response = threadStatusProvider.fetchTree(filter, null);
-        List<ThreadEntryModel> model = response.getModel();
+        Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        parameters.put(ThreadStatusDataProvider.ACTIVE_THREAD_FILTER_KEY, true);
+        TmfModelResponse<TmfTreeModel<@NonNull ThreadEntryModel>> response = threadStatusProvider.fetchTree(parameters, null);
+        TmfTreeModel<@NonNull ThreadEntryModel> model = response.getModel();
 
         if (model == null) {
             return Collections.emptySet();
         }
-        return Sets.newHashSet(Iterables.transform(model, ThreadEntryModel::getId));
+        HashSet<Long> onCpuThreads = Sets.newHashSet(Iterables.transform(model.getEntries(), ThreadEntryModel::getId));
+        return onCpuThreads == null ? Collections.emptySet() : onCpuThreads;
     }
 
     private static @NonNull Set<Long> getActiveThreads(TmfTimeRange winRange, @NonNull ITmfTrace trace) {
@@ -193,13 +198,16 @@
         long endTS = winRange.getEndTime().getValue();
 
         TimeQueryFilter filter = new TimeQueryFilter(beginTS, endTS, 2);
-        TmfModelResponse<List<ThreadEntryModel>> response = threadStatusProvider.fetchTree(filter, null);
-        List<ThreadEntryModel> model = response.getModel();
+        Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        parameters.put(ThreadStatusDataProvider.ACTIVE_THREAD_FILTER_KEY, true);
+        TmfModelResponse<TmfTreeModel<@NonNull ThreadEntryModel>> response = threadStatusProvider.fetchTree(parameters, null);
+        TmfTreeModel<@NonNull ThreadEntryModel> model = response.getModel();
 
         if (model == null) {
             return Collections.emptySet();
         }
-        return Sets.newHashSet(Iterables.transform(model, ThreadEntryModel::getId));
+        HashSet<Long> activeThreads = Sets.newHashSet(Iterables.transform(model.getEntries(), ThreadEntryModel::getId));
+        return activeThreads == null ? Collections.emptySet() : activeThreads;
     }
 
     /**
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/cpuusage/CpuUsageTreeViewer.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/cpuusage/CpuUsageTreeViewer.java
index cbe9c5e..5968f76 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/cpuusage/CpuUsageTreeViewer.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/cpuusage/CpuUsageTreeViewer.java
@@ -19,6 +19,7 @@
 import java.util.List;
 import java.util.Map;
 
+import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.widgets.Composite;
@@ -26,7 +27,9 @@
 import org.eclipse.tracecompass.analysis.os.linux.core.model.OsStrings;
 import org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.SubSecondTimeWithUnitFormat;
 import org.eclipse.tracecompass.internal.analysis.os.linux.core.cpuusage.CpuUsageDataProvider;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectedCpuQueryFilter;
+import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
 import org.eclipse.tracecompass.tmf.ui.viewers.tree.AbstractSelectTreeViewer;
@@ -115,6 +118,7 @@
     // Operations
     // ------------------------------------------------------------------------
 
+    @Deprecated
     @Override
     protected @Nullable TimeQueryFilter getFilter(long start, long end, boolean isSelection) {
         long newStart = Long.max(start, getStartTime());
@@ -127,6 +131,20 @@
     }
 
     @Override
+    protected @NonNull Map<String, Object> getParameters(long start, long end, boolean isSelection) {
+        long newStart = Long.max(start, getStartTime());
+        long newEnd = Long.min(end, getEndTime());
+
+        if (isSelection || newEnd < newStart) {
+            return Collections.emptyMap();
+        }
+
+        Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.selectionTimeQueryToMap(new SelectionTimeQueryFilter(start, end, 2, Collections.emptyList()));
+        parameters.put(CpuUsageDataProvider.REQUESTED_CPUS_KEY, CpuUsageView.getCpus(getTrace()));
+        return parameters;
+    }
+
+    @Override
     protected ITmfTreeViewerEntry modelToTree(long start, long end, List<ITmfTreeDataModel> model) {
         double time = end - start;
 
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/cpuusage/CpuUsageXYViewer.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/cpuusage/CpuUsageXYViewer.java
index b70f430..f6e6bbe 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/cpuusage/CpuUsageXYViewer.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/cpuusage/CpuUsageXYViewer.java
@@ -12,12 +12,15 @@
 
 package org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.cpuusage;
 
+import java.util.Map;
 import java.util.Set;
 
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.tracecompass.internal.analysis.os.linux.core.cpuusage.CpuUsageDataProvider;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectedCpuQueryFilter;
+import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.presentation.IYAppearance;
 import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.linecharts.TmfFilteredXYChartViewer;
@@ -50,12 +53,20 @@
         getSwtChart().getLegend().setVisible(false);
     }
 
+    @Deprecated
     @Override
     protected TimeQueryFilter createQueryFilter(long start, long end, int nb) {
         return new SelectedCpuQueryFilter(start, end, nb, getSelected(), CpuUsageView.getCpus(getTrace()));
     }
 
     @Override
+    protected @NonNull Map<String, Object> createQueryParameters(long start, long end, int nb) {
+        Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.selectionTimeQueryToMap(new SelectionTimeQueryFilter(start, end, nb, getSelected()));
+        parameters.put(CpuUsageDataProvider.REQUESTED_CPUS_KEY, CpuUsageView.getCpus(getTrace()));
+        return parameters;
+    }
+
+    @Override
     public IYAppearance getSeriesAppearance(@NonNull String seriesName) {
         if (seriesName.startsWith(CpuUsageDataProvider.TOTAL)) {
             return getPresentationProvider().getAppearance(seriesName, IYAppearance.Type.LINE, DEFAULT_SERIES_WIDTH);
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/memory/MemoryUsageTreeViewer.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/memory/MemoryUsageTreeViewer.java
index e172415..1de1295 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/memory/MemoryUsageTreeViewer.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/memory/MemoryUsageTreeViewer.java
@@ -9,11 +9,14 @@
 package org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.memory;
 
 import java.util.Comparator;
+import java.util.Map;
 
+import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.tracecompass.analysis.os.linux.core.memory.MemoryUsageTreeModel;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.tmf.core.model.filters.FilterTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.ui.viewers.tree.AbstractSelectTreeViewer;
@@ -86,12 +89,18 @@
         setLabelProvider(new MemoryLabelProvider());
     }
 
+    @Deprecated
     @Override
     protected @Nullable TimeQueryFilter getFilter(long start, long end, boolean isSelection) {
         return new FilterTimeQueryFilter(Long.min(start, end), Long.max(start, end), 2, fFiltered);
     }
 
     @Override
+    protected @NonNull Map<String, Object> getParameters(long start, long end, boolean isSelection) {
+        return FetchParametersUtils.filteredTimeQueryToMap(new FilterTimeQueryFilter(Long.min(start, end), Long.max(start, end), 2, fFiltered));
+    }
+
+    @Override
     protected ITmfTreeColumnDataProvider getColumnDataProvider() {
         return () -> {
             Comparator<TmfGenericTreeEntry<MemoryUsageTreeModel>> compareTid = Comparator.comparingInt(c -> c.getModel().getTid());
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/resources/ResourcesPresentationProvider.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/resources/ResourcesPresentationProvider.java
index 6af7407..c40f05f 100644
--- a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/resources/ResourcesPresentationProvider.java
+++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/resources/ResourcesPresentationProvider.java
@@ -21,6 +21,7 @@
 import org.eclipse.tracecompass.internal.analysis.os.linux.ui.Messages;
 import org.eclipse.tracecompass.internal.analysis.os.linux.ui.registry.LinuxStyle;
 import org.eclipse.tracecompass.internal.provisional.tmf.core.model.timegraph.ITimeGraphEntryModelWeighted;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphDataProvider;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphEntryModel;
@@ -192,7 +193,7 @@
 
     private static Map<String, String> getTooltip(ITimeGraphDataProvider<? extends TimeGraphEntryModel> provider, long id, long hoverTime) {
         SelectionTimeQueryFilter filter = new SelectionTimeQueryFilter(Collections.singletonList(hoverTime), Collections.singleton(id));
-        TmfModelResponse<Map<String, String>> response = provider.fetchTooltip(filter, null);
+        TmfModelResponse<Map<String, String>> response = provider.fetchTooltip(FetchParametersUtils.selectionTimeQueryToMap(filter), null);
         Map<String, String> tooltip = response.getModel();
 
         if (tooltip == null) {
diff --git a/analysis/org.eclipse.tracecompass.analysis.profiling.core/src/org/eclipse/tracecompass/internal/analysis/profiling/core/callstack/provider/CallStackDataProvider.java b/analysis/org.eclipse.tracecompass.analysis.profiling.core/src/org/eclipse/tracecompass/internal/analysis/profiling/core/callstack/provider/CallStackDataProvider.java
index 04db1d8..e257a97 100644
--- a/analysis/org.eclipse.tracecompass.analysis.profiling.core/src/org/eclipse/tracecompass/internal/analysis/profiling/core/callstack/provider/CallStackDataProvider.java
+++ b/analysis/org.eclipse.tracecompass.analysis.profiling.core/src/org/eclipse/tracecompass/internal/analysis/profiling/core/callstack/provider/CallStackDataProvider.java
@@ -25,19 +25,22 @@
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.analysis.profiling.core.callstack.CallStackAnalysis;
-import org.eclipse.tracecompass.internal.tmf.core.model.filters.TimeGraphStateQueryFilter;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.internal.tmf.core.model.timegraph.AbstractTimeGraphDataProvider;
 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
 import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
 import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
 import org.eclipse.tracecompass.tmf.core.model.CommonStatusMessage;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphArrow;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphRowModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphState;
+import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphRowModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphState;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 import org.eclipse.tracecompass.tmf.core.symbols.ISymbolProvider;
@@ -116,14 +119,14 @@
     }
 
     @Override
-    protected List<CallStackEntryModel> getTree(ITmfStateSystem ss, TimeQueryFilter filter,
+    protected TmfTreeModel<@NonNull CallStackEntryModel> getTree(ITmfStateSystem ss, Map<String, Object> parameters,
             @Nullable IProgressMonitor monitor) throws StateSystemDisposedException {
         long start = ss.getStartTime();
         long end = ss.getCurrentEndTime();
 
         ImmutableList.Builder<CallStackEntryModel> builder = ImmutableList.builder();
         long traceId = getId(ITmfStateSystem.ROOT_ATTRIBUTE);
-        builder.add(new CallStackEntryModel(traceId, -1, getTrace().getName(), start, end, CallStackEntryModel.TRACE, UNKNOWN_TID));
+        builder.add(new CallStackEntryModel(traceId, -1, Collections.singletonList(getTrace().getName()), start, end, CallStackEntryModel.TRACE, UNKNOWN_TID));
 
         List<Integer> processQuarks = ss.getQuarks(getAnalysisModule().getProcessesPattern());
         SubMonitor subMonitor = SubMonitor.convert(monitor, "CallStackDataProvider#fetchTree", processQuarks.size()); //$NON-NLS-1$
@@ -141,7 +144,7 @@
                 String processName = ss.getAttributeName(processQuark);
                 Object processValue = fullEnd.get(processQuark).getValue();
                 pid = getThreadProcessId(processName, processValue);
-                builder.add(new CallStackEntryModel(threadParentId, traceId, processName, start, end,
+                builder.add(new CallStackEntryModel(threadParentId, traceId, Collections.singletonList(processName), start, end,
                         CallStackEntryModel.PROCESS, pid));
             }
 
@@ -169,7 +172,7 @@
             subMonitor.worked(1);
         }
 
-        return builder.build();
+        return new TmfTreeModel<>(Collections.emptyList(), builder.build());
     }
 
     private CallStackEntryModel createThread(ITmfStateSystem ss, long start, long end, int threadQuark, long processId, int callStackQuark,
@@ -184,7 +187,7 @@
         int threadId = getThreadProcessId(threadName, threadStateValue);
         ITmfStateInterval startInterval = fullStart.get(callStackQuark);
         long threadStart = startInterval.getValue() == null ? Long.min(startInterval.getEndTime() + 1, end) : start;
-        return new CallStackEntryModel(getId(threadQuark), processId, threadName, threadStart, threadEnd, CallStackEntryModel.THREAD, threadId);
+        return new CallStackEntryModel(getId(threadQuark), processId, Collections.singletonList(threadName), threadStart, threadEnd, CallStackEntryModel.THREAD, threadId);
     }
 
     private void createStackEntries(List<Integer> callStackAttributes, long start, long end, int pid,
@@ -192,7 +195,7 @@
         int level = 1;
         for (int stackLevelQuark : callStackAttributes) {
             long id = getId(stackLevelQuark);
-            builder.add(new CallStackEntryModel(id, callStackParent, threadName, start, end, level, pid));
+            builder.add(new CallStackEntryModel(id, callStackParent, Collections.singletonList(threadName), start, end, level, pid));
             fQuarkToPid.put(stackLevelQuark, pid);
             level++;
         }
@@ -210,16 +213,20 @@
     }
 
     @Override
-    protected List<ITimeGraphRowModel> getRowModel(ITmfStateSystem ss, SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor)
+    protected TimeGraphModel getRowModel(ITmfStateSystem ss, @NonNull Map<@NonNull String, @NonNull Object> parameters, @Nullable IProgressMonitor monitor)
             throws StateSystemDisposedException {
+        SelectionTimeQueryFilter filter = FetchParametersUtils.createSelectionTimeQuery(parameters);
+        if (filter == null) {
+            return null;
+        }
         Map<@NonNull Long, @NonNull Integer> entries = getSelectedEntries(filter);
         if (entries.size() == 1 && filter.getTimesRequested().length == 2) {
             // this is a request for a follow event.
             Entry<@NonNull Long, @NonNull Integer> entry = entries.entrySet().iterator().next();
             if (filter.getStart() == Long.MIN_VALUE) {
-                return getFollowEvent(ss, entry, filter.getEnd(), false);
+                return new TimeGraphModel(getFollowEvent(ss, entry, filter.getEnd(), false));
             } else if (filter.getEnd() == Long.MAX_VALUE) {
-                return getFollowEvent(ss, entry, filter.getStart(), true);
+                return new TimeGraphModel(getFollowEvent(ss, entry, filter.getStart(), true));
             }
         }
 
@@ -237,12 +244,12 @@
         subMonitor.worked(1);
 
         Map<@NonNull Integer, @NonNull Predicate<@NonNull Multimap<@NonNull String, @NonNull String>>> predicates = new HashMap<>();
-        if (filter instanceof TimeGraphStateQueryFilter) {
-            TimeGraphStateQueryFilter timeEventFilter = (TimeGraphStateQueryFilter) filter;
-            predicates.putAll(computeRegexPredicate(timeEventFilter));
+        Multimap<@NonNull Integer, @NonNull String> regexesMap = DataProviderParameterUtils.extractRegexFilter(parameters);
+        if (regexesMap != null) {
+            predicates.putAll(computeRegexPredicate(regexesMap));
         }
 
-        List<ITimeGraphRowModel> rows = new ArrayList<>();
+        @NonNull List<@NonNull ITimeGraphRowModel> rows = new ArrayList<>();
         for (Map.Entry<Long, Integer> entry : entries.entrySet()) {
             if (subMonitor.isCanceled()) {
                 return null;
@@ -258,7 +265,7 @@
             rows.add(new TimeGraphRowModel(entry.getKey(), eventList));
         }
         subMonitor.worked(1);
-        return rows;
+        return new TimeGraphModel(rows);
     }
 
     private ITimeGraphState createTimeGraphState(ITmfStateInterval interval) {
@@ -273,8 +280,15 @@
         return new TimeGraphState(startTime, duration, Integer.MIN_VALUE);
     }
 
+    @Deprecated
     @Override
-    public TmfModelResponse<List<ITimeGraphArrow>> fetchArrows(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public @NonNull TmfModelResponse<@NonNull List<@NonNull ITimeGraphArrow>> fetchArrows(@NonNull TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        Map<String, Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        return fetchArrows(parameters, monitor);
+    }
+
+    @Override
+    public @NonNull TmfModelResponse<@NonNull List<@NonNull ITimeGraphArrow>> fetchArrows(Map<String, Object> parameters, @Nullable IProgressMonitor monitor) {
         return new TmfModelResponse<>(null, ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
     }
 
@@ -342,8 +356,15 @@
         return null;
     }
 
+    @Deprecated
     @Override
-    public TmfModelResponse<Map<String, String>> fetchTooltip(SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public @NonNull TmfModelResponse<@NonNull Map<@NonNull String, @NonNull String>> fetchTooltip(@NonNull SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        Map<String, Object> parameters = FetchParametersUtils.selectionTimeQueryToMap(filter);
+        return fetchTooltip(parameters, monitor);
+    }
+
+    @Override
+    public @NonNull TmfModelResponse<@NonNull Map<@NonNull String, @NonNull String>> fetchTooltip(Map<String, Object> parameters, @Nullable IProgressMonitor monitor) {
         return new TmfModelResponse<>(Collections.emptyMap(), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
     }
 
diff --git a/analysis/org.eclipse.tracecompass.analysis.profiling.core/src/org/eclipse/tracecompass/internal/analysis/profiling/core/callstack/provider/CallStackDataProviderFactory.java b/analysis/org.eclipse.tracecompass.analysis.profiling.core/src/org/eclipse/tracecompass/internal/analysis/profiling/core/callstack/provider/CallStackDataProviderFactory.java
index dd02d0f..b13d148 100644
--- a/analysis/org.eclipse.tracecompass.analysis.profiling.core/src/org/eclipse/tracecompass/internal/analysis/profiling/core/callstack/provider/CallStackDataProviderFactory.java
+++ b/analysis/org.eclipse.tracecompass.analysis.profiling.core/src/org/eclipse/tracecompass/internal/analysis/profiling/core/callstack/provider/CallStackDataProviderFactory.java
@@ -9,16 +9,25 @@
 
 package org.eclipse.tracecompass.internal.analysis.profiling.core.callstack.provider;
 
+import java.util.Collection;
+import java.util.Collections;
 import java.util.Iterator;
+import java.util.Objects;
 
+import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.analysis.profiling.core.callstack.CallStackAnalysis;
+import org.eclipse.tracecompass.internal.tmf.core.model.DataProviderDescriptor;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor.ProviderType;
 import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderFactory;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataProvider;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
 
+import com.google.common.collect.Iterables;
+
 /**
  * {@link CallStackDataProvider} factory, uses the data provider extension
  * point.
@@ -27,6 +36,13 @@
  */
 public class CallStackDataProviderFactory implements IDataProviderFactory {
 
+    private static final IDataProviderDescriptor DESCRIPTOR = new DataProviderDescriptor.Builder()
+            .setId(CallStackDataProvider.ID)
+            .setName(Objects.requireNonNull(Messages.CallStackDataProviderFactory_title))
+            .setDescription(Objects.requireNonNull(Messages.CallStackDataProviderFactory_descriptionText))
+            .setProviderType(ProviderType.TIME_GRAPH)
+            .build();
+
     @Override
     public @Nullable ITmfTreeDataProvider<? extends ITmfTreeDataModel> createProvider(ITmfTrace trace) {
         Iterator<CallStackAnalysis> modules = TmfTraceUtils.getAnalysisModulesOfClass(trace, CallStackAnalysis.class).iterator();
@@ -38,4 +54,9 @@
         return null;
     }
 
+    @Override
+    public Collection<IDataProviderDescriptor> getDescriptors(@NonNull ITmfTrace trace) {
+        Iterable<@NonNull CallStackAnalysis> modules = TmfTraceUtils.getAnalysisModulesOfClass(trace, CallStackAnalysis.class);
+        return !Iterables.isEmpty(modules) ? Collections.singletonList(DESCRIPTOR) : Collections.emptyList();
+    }
 }
diff --git a/analysis/org.eclipse.tracecompass.analysis.profiling.core/src/org/eclipse/tracecompass/internal/analysis/profiling/core/callstack/provider/CallStackEntryModel.java b/analysis/org.eclipse.tracecompass.analysis.profiling.core/src/org/eclipse/tracecompass/internal/analysis/profiling/core/callstack/provider/CallStackEntryModel.java
index 404c1b9..7bde5fe 100644
--- a/analysis/org.eclipse.tracecompass.analysis.profiling.core/src/org/eclipse/tracecompass/internal/analysis/profiling/core/callstack/provider/CallStackEntryModel.java
+++ b/analysis/org.eclipse.tracecompass.analysis.profiling.core/src/org/eclipse/tracecompass/internal/analysis/profiling/core/callstack/provider/CallStackEntryModel.java
@@ -9,8 +9,10 @@
 
 package org.eclipse.tracecompass.internal.analysis.profiling.core.callstack.provider;
 
+import java.util.List;
 import java.util.Objects;
 
+import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphEntryModel;
 
@@ -44,8 +46,8 @@
      *            unique ID for this {@link CallStackEntryModel}
      * @param parentId
      *            parent's ID to build the tree
-     * @param name
-     *            entry's name
+     * @param labels
+     *            entry's labels
      * @param startTime
      *            entry's start time
      * @param endTime
@@ -57,8 +59,8 @@
      * @param pid
      *            entry's PID or TID if is a thread
      */
-    public CallStackEntryModel(long id, long parentId, String name, long startTime, long endTime, int stackLevel, int pid) {
-        super(id, parentId, name, startTime, endTime);
+    public CallStackEntryModel(long id, long parentId, @NonNull List<@NonNull String> labels, long startTime, long endTime, int stackLevel, int pid) {
+        super(id, parentId, labels, startTime, endTime);
         fStackLevel = stackLevel;
         fPid = pid;
     }
diff --git a/analysis/org.eclipse.tracecompass.analysis.profiling.core/src/org/eclipse/tracecompass/internal/analysis/profiling/core/callstack/provider/Messages.java b/analysis/org.eclipse.tracecompass.analysis.profiling.core/src/org/eclipse/tracecompass/internal/analysis/profiling/core/callstack/provider/Messages.java
index a177759..4eca726 100644
--- a/analysis/org.eclipse.tracecompass.analysis.profiling.core/src/org/eclipse/tracecompass/internal/analysis/profiling/core/callstack/provider/Messages.java
+++ b/analysis/org.eclipse.tracecompass.analysis.profiling.core/src/org/eclipse/tracecompass/internal/analysis/profiling/core/callstack/provider/Messages.java
@@ -33,6 +33,15 @@
      */
     public static @Nullable String CallStackStateProvider_IncoherentCallstack;
 
+    /**
+     * Name of the data provider shown to the user
+     */
+    public static @Nullable String CallStackDataProviderFactory_title;
+    /**
+     * Help text for the data descriptor
+     */
+    public static @Nullable String CallStackDataProviderFactory_descriptionText;
+
     static {
         // initialize resource bundle
         NLS.initializeMessages(BUNDLE_NAME, Messages.class);
diff --git a/analysis/org.eclipse.tracecompass.analysis.profiling.core/src/org/eclipse/tracecompass/internal/analysis/profiling/core/callstack/provider/messages.properties b/analysis/org.eclipse.tracecompass.analysis.profiling.core/src/org/eclipse/tracecompass/internal/analysis/profiling/core/callstack/provider/messages.properties
index d4d9b30..c3a7288 100644
--- a/analysis/org.eclipse.tracecompass.analysis.profiling.core/src/org/eclipse/tracecompass/internal/analysis/profiling/core/callstack/provider/messages.properties
+++ b/analysis/org.eclipse.tracecompass.analysis.profiling.core/src/org/eclipse/tracecompass/internal/analysis/profiling/core/callstack/provider/messages.properties
@@ -11,4 +11,6 @@
 ###############################################################################
 
 CallStackStateProvider_UnmatchedPoppedValue=Function exit name in event ({0}) different from the expected one ({1}). You may have lost events in your trace.
-CallStackStateProvider_IncoherentCallstack=Incoherent callstack found on ({0}) occasions
\ No newline at end of file
+CallStackStateProvider_IncoherentCallstack=Incoherent callstack found on ({0}) occasions
+CallStackDataProviderFactory_title=Flame Chart
+CallStackDataProviderFactory_descriptionText=Show a call stack over time
\ No newline at end of file
diff --git a/analysis/org.eclipse.tracecompass.analysis.profiling.ui/src/org/eclipse/tracecompass/analysis/profiling/ui/views/flamechart/FlameChartView.java b/analysis/org.eclipse.tracecompass.analysis.profiling.ui/src/org/eclipse/tracecompass/analysis/profiling/ui/views/flamechart/FlameChartView.java
index a3e3778..8c4c1e3 100644
--- a/analysis/org.eclipse.tracecompass.analysis.profiling.ui/src/org/eclipse/tracecompass/analysis/profiling/ui/views/flamechart/FlameChartView.java
+++ b/analysis/org.eclipse.tracecompass.analysis.profiling.ui/src/org/eclipse/tracecompass/analysis/profiling/ui/views/flamechart/FlameChartView.java
@@ -43,6 +43,7 @@
 import org.eclipse.tracecompass.internal.analysis.profiling.core.callstack.provider.CallStackEntryModel;
 import org.eclipse.tracecompass.internal.analysis.profiling.ui.Activator;
 import org.eclipse.tracecompass.internal.analysis.profiling.ui.views.flamechart.Messages;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderManager;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphDataProvider;
@@ -50,6 +51,7 @@
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphRowModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphState;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphEntryModel;
+import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphModel;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
@@ -456,10 +458,10 @@
                 Map<Long, TimeGraphEntry> map = Maps.uniqueIndex(unfiltered, e -> e.getModel().getId());
                 // use time -1 as a lower bound for the end of Time events to be included.
                 SelectionTimeQueryFilter filter = new SelectionTimeQueryFilter(time - 1, time, 2, map.keySet());
-                TmfModelResponse<@NonNull List<@NonNull ITimeGraphRowModel>> response = traceEntry.getProvider().fetchRowModel(filter, null);
-                List<@NonNull ITimeGraphRowModel> model = response.getModel();
+                TmfModelResponse<@NonNull TimeGraphModel> response = traceEntry.getProvider().fetchRowModel(FetchParametersUtils.selectionTimeQueryToMap(filter), null);
+                TimeGraphModel model = response.getModel();
                 if (model != null) {
-                    for (ITimeGraphRowModel row : model) {
+                    for (ITimeGraphRowModel row : model.getRows()) {
                         syncToRow(row, time, map);
                     }
                 }
@@ -561,12 +563,12 @@
                         ITimeGraphDataProvider<? extends TimeGraphEntryModel> provider = getProvider(callStackEntry);
                         long selectionBegin = viewer.getSelectionBegin();
                         SelectionTimeQueryFilter filter = new SelectionTimeQueryFilter(selectionBegin, Long.MAX_VALUE, 2, Collections.singleton(callStackEntry.getModel().getId()));
-                        TmfModelResponse<@NonNull List<@NonNull ITimeGraphRowModel>> response = provider.fetchRowModel(filter, null);
-                        List<@NonNull ITimeGraphRowModel> model = response.getModel();
-                        if (model == null || model.size() != 1) {
+                        TmfModelResponse<@NonNull TimeGraphModel> response = provider.fetchRowModel(FetchParametersUtils.selectionTimeQueryToMap(filter), null);
+                        TimeGraphModel model = response.getModel();
+                        if (model == null || model.getRows().size() != 1) {
                             return;
                         }
-                        List<@NonNull ITimeGraphState> row = model.get(0).getStates();
+                        List<@NonNull ITimeGraphState> row = model.getRows().get(0).getStates();
                         if (row.size() != 1) {
                             return;
                         }
@@ -613,12 +615,12 @@
                         ITimeGraphDataProvider<? extends TimeGraphEntryModel> provider = getProvider(callStackEntry);
                         long selectionBegin = viewer.getSelectionBegin();
                         SelectionTimeQueryFilter filter = new SelectionTimeQueryFilter(Lists.newArrayList(Long.MIN_VALUE, selectionBegin), Collections.singleton(callStackEntry.getModel().getId()));
-                        TmfModelResponse<@NonNull List<@NonNull ITimeGraphRowModel>> response = provider.fetchRowModel(filter, null);
-                        List<@NonNull ITimeGraphRowModel> model = response.getModel();
-                        if (model == null || model.size() != 1) {
+                        TmfModelResponse<@NonNull TimeGraphModel> response = provider.fetchRowModel(FetchParametersUtils.selectionTimeQueryToMap(filter), null);
+                        TimeGraphModel model = response.getModel();
+                        if (model == null || model.getRows().size() != 1) {
                             return;
                         }
-                        List<@NonNull ITimeGraphState> row = model.get(0).getStates();
+                        List<@NonNull ITimeGraphState> row = model.getRows().get(0).getStates();
                         if (row.size() != 1) {
                             return;
                         }
diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/analysis/timing/core/segmentstore/SegmentStoreStatisticsModel.java b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/analysis/timing/core/segmentstore/SegmentStoreStatisticsModel.java
index 340bc59..4c82123 100644
--- a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/analysis/timing/core/segmentstore/SegmentStoreStatisticsModel.java
+++ b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/analysis/timing/core/segmentstore/SegmentStoreStatisticsModel.java
@@ -9,6 +9,9 @@
 
 package org.eclipse.tracecompass.analysis.timing.core.segmentstore;
 
+import java.util.Collections;
+import java.util.List;
+
 import org.eclipse.tracecompass.analysis.timing.core.statistics.IStatistics;
 import org.eclipse.tracecompass.segmentstore.core.ISegment;
 import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeDataModel;
@@ -46,7 +49,25 @@
      *            model.
      */
     public SegmentStoreStatisticsModel(long id, long parentId, String name, IStatistics<ISegment> statistics) {
-        super(id, parentId, name);
+        this(id, parentId, Collections.singletonList(name), statistics);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param id
+     *            The id of the model
+     * @param parentId
+     *            The parent id of this model. If it has none, give <code>-1</code>.
+     * @param labels
+     *            The labels of this model
+     * @param statistics
+     *            the {@link IStatistics} who's values will be copied into this
+     *            model.
+     * @since 5.0
+     */
+    public SegmentStoreStatisticsModel(long id, long parentId, List<String> labels, IStatistics<ISegment> statistics) {
+        super(id, parentId, labels);
         fMin = statistics.getMin();
         fMax = statistics.getMax();
         fNbElements = statistics.getNbElements();
diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/Messages.java b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/Messages.java
index b3664d0..a79fa52 100644
--- a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/Messages.java
+++ b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/Messages.java
@@ -64,6 +64,16 @@
      */
     public static @Nullable String SegmentStoreStatisticsDataProviderFactory_AnalysisName;
 
+    /**
+     * Title of the data provider
+     */
+    public static @Nullable String SegmentStoreScatterGraphDataProvider_title;
+
+    /**
+     * Description of the data provider
+     */
+    public static @Nullable String SegmentStoreScatterGraphDataProvider_description;
+
     static {
         // initialize resource bundle
         NLS.initializeMessages(BUNDLE_NAME, Messages.class);
diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/SegmentStoreScatterDataProvider.java b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/SegmentStoreScatterDataProvider.java
index 75c3945..c6331c5 100644
--- a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/SegmentStoreScatterDataProvider.java
+++ b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/SegmentStoreScatterDataProvider.java
@@ -30,21 +30,25 @@
 import org.eclipse.tracecompass.internal.analysis.timing.core.Activator;
 import org.eclipse.tracecompass.internal.tmf.core.model.AbstractTmfTraceDataProvider;
 import org.eclipse.tracecompass.internal.tmf.core.model.TmfXyResponseFactory;
-import org.eclipse.tracecompass.internal.tmf.core.model.filters.IRegexQuery;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.internal.tmf.core.model.xy.TmfTreeXYCompositeDataProvider;
 import org.eclipse.tracecompass.segmentstore.core.ISegment;
 import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
 import org.eclipse.tracecompass.segmentstore.core.SegmentComparators;
 import org.eclipse.tracecompass.segmentstore.core.segment.interfaces.INamedSegment;
 import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
+import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
 import org.eclipse.tracecompass.tmf.core.model.CommonStatusMessage;
 import org.eclipse.tracecompass.tmf.core.model.SeriesModel;
+import org.eclipse.tracecompass.tmf.core.model.SeriesModel.SeriesModelBuilder;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.IFilterProperty;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataProvider;
 import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeDataModel;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
+import org.eclipse.tracecompass.tmf.core.model.xy.ISeriesModel;
 import org.eclipse.tracecompass.tmf.core.model.xy.ITmfTreeXYDataProvider;
 import org.eclipse.tracecompass.tmf.core.model.xy.ITmfXyModel;
 import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
@@ -57,7 +61,6 @@
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableList.Builder;
 import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
 import com.google.common.collect.Multimap;
 import com.google.common.primitives.Doubles;
 import com.google.common.primitives.Ints;
@@ -242,13 +245,17 @@
      * @since 4.0
      */
     @Override
-    public TmfModelResponse<List<TmfTreeDataModel>> fetchTree(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public TmfModelResponse<TmfTreeModel<TmfTreeDataModel>> fetchTree(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         ISegmentStoreProvider provider = fProvider;
         ISegmentStore<ISegment> segStore = provider.getSegmentStore();
 
         if (segStore == null) {
             return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, CommonStatusMessage.ANALYSIS_INITIALIZATION_FAILED);
         }
+        TimeQueryFilter filter = FetchParametersUtils.createTimeQuery(fetchParameters);
+        if (filter == null) {
+            return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, CommonStatusMessage.INCORRECT_QUERY_PARAMETERS);
+        }
         long start = filter.getStart();
         long end = filter.getEnd();
         final Iterable<ISegment> intersectingElements = Iterables.filter(segStore.getIntersectingElements(start, end), s -> s.getStart() >= start);
@@ -266,7 +273,7 @@
         }
 
         Builder<TmfTreeDataModel> nodes = new ImmutableList.Builder<>();
-        nodes.add(new TmfTreeDataModel(fTraceId, -1, String.valueOf(getTrace().getName())));
+        nodes.add(new TmfTreeDataModel(fTraceId, -1, Collections.singletonList(String.valueOf(getTrace().getName()))));
         Map<IGroupingSegmentAspect, Map<String, Long>> names = new HashMap<>();
 
         for (Entry<String, INamedSegment> series : segmentTypes.entrySet()) {
@@ -294,12 +301,12 @@
             nodes.add(new TmfTreeDataModel(seriesId, parentId, series.getKey()));
         }
 
-        return new TmfModelResponse<>(nodes.build(), complete ? ITmfResponse.Status.COMPLETED : ITmfResponse.Status.RUNNING,
-                complete ? CommonStatusMessage.COMPLETED : CommonStatusMessage.RUNNING);
+        return new TmfModelResponse<>(new TmfTreeModel<>(Collections.emptyList(), nodes.build()), complete ? ITmfResponse.Status.COMPLETED : ITmfResponse.Status.RUNNING,
+                complete ? CommonStatusMessage.COMPLETED: CommonStatusMessage.RUNNING);
     }
 
     @Override
-    public TmfModelResponse<ITmfXyModel> fetchXY(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public TmfModelResponse<ITmfXyModel> fetchXY(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         ISegmentStoreProvider provider = fProvider;
 
         // FIXME: There is no way to get the running status of a segment store analysis,
@@ -314,10 +321,22 @@
             return TmfXyResponseFactory.createFailedResponse(Objects.requireNonNull(Messages.SegmentStoreDataProvider_SegmentNotAvailable));
         }
 
+        // TODO server: Parameters validation should be handle separately. It
+        // can be either in the data provider itself or before calling it. It
+        // will avoid the creation of filters and the content of the map can be
+        // use directly.
+        TimeQueryFilter filter = FetchParametersUtils.createSelectionTimeQuery(fetchParameters);
+        if (filter == null) {
+            filter = FetchParametersUtils.createTimeQuery(fetchParameters);
+            if (filter == null) {
+                return TmfXyResponseFactory.createFailedResponse(CommonStatusMessage.INCORRECT_QUERY_PARAMETERS);
+            }
+        }
+
         Map<@NonNull Integer, @NonNull Predicate<@NonNull Multimap<@NonNull String, @NonNull String>>> predicates = new HashMap<>();
-        if (filter instanceof IRegexQuery) {
-            IRegexQuery regexFilter = (IRegexQuery) filter;
-            predicates.putAll(computeRegexPredicate(regexFilter));
+        Multimap<@NonNull Integer, @NonNull String> regexesMap = DataProviderParameterUtils.extractRegexFilter(fetchParameters);
+        if (regexesMap != null) {
+            predicates.putAll(computeRegexPredicate(regexesMap));
         }
 
         long start = filter.getStart();
@@ -358,8 +377,13 @@
             addPoint(thisSeries, segment, predicates, monitor);
         }
 
+        Map<String, ISeriesModel> seriesModelMap = new HashMap<>();
+        for (Entry<String, Series> entry : types.entrySet()) {
+            SeriesModel seriesModel = entry.getValue().build();
+            seriesModelMap.put(Long.toString(seriesModel.getId()), seriesModel);
+        }
         return TmfXyResponseFactory.create(Objects.requireNonNull(Messages.SegmentStoreScatterGraphViewer_title),
-                Maps.transformValues(types, Series::build), complete);
+                seriesModelMap, complete);
     }
 
     private static String getSegmentName(ISegment segment) {
@@ -433,7 +457,9 @@
         }
 
         public SeriesModel build() {
-            return new SeriesModel(getId(), getName(), Longs.toArray(fXValues), Doubles.toArray(fYValues), Ints.toArray(fProperties));
+            SeriesModelBuilder builder = new SeriesModel.SeriesModelBuilder(getId(), getName(), Longs.toArray(fXValues), Doubles.toArray(fYValues));
+            builder.setProperties(Ints.toArray(fProperties)).build();
+            return builder.setProperties(Ints.toArray(fProperties)).build();
         }
 
         private long getId() {
@@ -479,4 +505,24 @@
         return fId;
     }
 
+    @Deprecated
+    @Override
+    public TmfModelResponse<ITmfXyModel> fetchXY(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        Map<String, Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        return fetchXY(parameters, monitor);
+    }
+
+    @Deprecated
+    @Override
+    public TmfModelResponse<List<TmfTreeDataModel>> fetchTree(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        Map<String, Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        TmfModelResponse<TmfTreeModel<TmfTreeDataModel>> response = fetchTree(parameters, monitor);
+        TmfTreeModel<@NonNull TmfTreeDataModel> model = response.getModel();
+        List<TmfTreeDataModel> treeModel = null;
+        if (model != null) {
+            treeModel = model.getEntries();
+        }
+        return new TmfModelResponse<>(treeModel, response.getStatus(), response.getStatusMessage());
+    }
+
 }
diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/SegmentStoreScatterDataProviderFactory.java b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/SegmentStoreScatterDataProviderFactory.java
index 95bfda7..fe56c24 100644
--- a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/SegmentStoreScatterDataProviderFactory.java
+++ b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/SegmentStoreScatterDataProviderFactory.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2017 École Polytechnique de Montréal
+ * Copyright (c) 2017, 2019 École Polytechnique de Montréal
  *
  * All rights reserved. This program and the accompanying materials are
  * made available under the terms of the Eclipse Public License v1.0 which
@@ -9,16 +9,28 @@
 
 package org.eclipse.tracecompass.internal.analysis.timing.core.segmentstore;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 
 import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tracecompass.analysis.timing.core.segmentstore.ISegmentStoreProvider;
+import org.eclipse.tracecompass.internal.tmf.core.model.DataProviderDescriptor;
 import org.eclipse.tracecompass.internal.tmf.core.model.xy.TmfTreeXYCompositeDataProvider;
+import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
+import org.eclipse.tracecompass.tmf.core.component.DataProviderConstants;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor.ProviderType;
 import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderFactory;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataProvider;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
 
 /**
  * @author Geneviève Bastien
@@ -48,4 +60,24 @@
 
     }
 
+    @Override
+    public Collection<IDataProviderDescriptor> getDescriptors(ITmfTrace trace) {
+        Iterable<ISegmentStoreProvider> modules = TmfTraceUtils.getAnalysisModulesOfClass(trace, ISegmentStoreProvider.class);
+        List<IDataProviderDescriptor> descriptors = new ArrayList<>();
+        Set<String> existingModules = new HashSet<>();
+        for (ISegmentStoreProvider module : modules) {
+            IAnalysisModule analysis = (IAnalysisModule) module;
+            // Only add analysis once per trace (which could be an experiment)
+            if (!existingModules.contains(analysis.getId())) {
+                DataProviderDescriptor.Builder builder = new DataProviderDescriptor.Builder();
+                builder.setId(SegmentStoreScatterDataProvider.ID + DataProviderConstants.ID_SEPARATOR + analysis.getId())
+                    .setName(Objects.requireNonNull(NLS.bind(Messages.SegmentStoreScatterGraphDataProvider_title, analysis.getName())))
+                    .setDescription(Objects.requireNonNull(NLS.bind(Messages.SegmentStoreScatterGraphDataProvider_description, analysis.getHelpText())))
+                    .setProviderType(ProviderType.TREE_TIME_XY);
+                descriptors.add(builder.build());
+                existingModules.add(analysis.getId());
+            }
+        }
+        return descriptors;
+    }
 }
diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/SegmentStoreStatisticsDataProvider.java b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/SegmentStoreStatisticsDataProvider.java
index af58bf4..365f8cd 100644
--- a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/SegmentStoreStatisticsDataProvider.java
+++ b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/SegmentStoreStatisticsDataProvider.java
@@ -21,19 +21,23 @@
 
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.analysis.timing.core.segmentstore.SegmentStoreStatisticsModel;
 import org.eclipse.tracecompass.analysis.timing.core.segmentstore.statistics.AbstractSegmentStatisticsAnalysis;
 import org.eclipse.tracecompass.analysis.timing.core.statistics.IStatistics;
 import org.eclipse.tracecompass.internal.tmf.core.model.AbstractTmfTraceDataProvider;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.segmentstore.core.ISegment;
 import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
+import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
 import org.eclipse.tracecompass.tmf.core.model.CommonStatusMessage;
 import org.eclipse.tracecompass.tmf.core.model.filters.FilterTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataProvider;
-import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.response.ITmfResponse.Status;
+import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 
 /**
@@ -99,8 +103,21 @@
         fProvider = provider;
     }
 
+    @Deprecated
     @Override
     public TmfModelResponse<List<SegmentStoreStatisticsModel>> fetchTree(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        Map<String, Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        TmfModelResponse<@NonNull TmfTreeModel<@NonNull SegmentStoreStatisticsModel>> response = fetchTree(parameters, monitor);
+        TmfTreeModel<@NonNull SegmentStoreStatisticsModel> model = response.getModel();
+        List<SegmentStoreStatisticsModel> treeModel = null;
+        if (model != null) {
+            treeModel = model.getEntries();
+        }
+        return new TmfModelResponse<>(treeModel, response.getStatus(), response.getStatusMessage());
+    }
+
+    @Override
+    public TmfModelResponse<TmfTreeModel<SegmentStoreStatisticsModel>> fetchTree(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         if (monitor != null) {
             fProvider.waitForCompletion(monitor);
             if (monitor.isCanceled()) {
@@ -116,22 +133,24 @@
         }
 
         List<SegmentStoreStatisticsModel> list = new ArrayList<>();
-        list.add(new SegmentStoreStatisticsModel(fTraceId, -1, Objects.requireNonNull(getTrace().getName()), statsTotal));
+        list.add(new SegmentStoreStatisticsModel(fTraceId, -1, Collections.singletonList(Objects.requireNonNull(getTrace().getName())), statsTotal));
 
         /*
          * Add statistics for full duration.
          */
         long totalId = getUniqueId(TOTAL_PREFIX);
-        list.add(new SegmentStoreStatisticsModel(totalId, fTraceId, Objects.requireNonNull(Messages.SegmentStoreStatisticsDataProvider_Total), statsTotal));
+        list.add(new SegmentStoreStatisticsModel(totalId, fTraceId, Collections.singletonList(Objects.requireNonNull(Messages.SegmentStoreStatisticsDataProvider_Total)), statsTotal));
         Map<String, IStatistics<ISegment>> totalStats = fProvider.getStatsPerType();
         for (Entry<String, IStatistics<ISegment>> entry : totalStats.entrySet()) {
-            list.add(new SegmentStoreStatisticsModel(getUniqueId(TOTAL_PREFIX + entry.getKey()), totalId, entry.getKey(), entry.getValue()));
+            list.add(new SegmentStoreStatisticsModel(getUniqueId(TOTAL_PREFIX + entry.getKey()), totalId, Collections.singletonList(entry.getKey()), entry.getValue()));
         }
 
         /*
          * Add statistics for selection if any.
          */
-        if (filter instanceof FilterTimeQueryFilter && ((FilterTimeQueryFilter) filter).isFiltered()) {
+        TimeQueryFilter filter = FetchParametersUtils.createTimeQuery(fetchParameters);
+        Boolean isFiltered = DataProviderParameterUtils.extractIsFiltered(fetchParameters);
+        if (filter != null && isFiltered != null && isFiltered) {
             long start = filter.getStart();
             long end = filter.getEnd();
 
@@ -142,13 +161,13 @@
             }
 
             long selectionId = getUniqueId(SELECTION_PREFIX);
-            list.add(new SegmentStoreStatisticsModel(selectionId, fTraceId, Objects.requireNonNull(Messages.SegmentStoreStatisticsDataProvider_Selection), statsForRange));
+            list.add(new SegmentStoreStatisticsModel(selectionId, fTraceId, Collections.singletonList(Objects.requireNonNull(Messages.SegmentStoreStatisticsDataProvider_Selection)), statsForRange));
             Map<String, IStatistics<ISegment>> selectionStats = fProvider.getStatsPerTypeForRange(start, end, nonNullMonitor);
             for (Entry<String, IStatistics<ISegment>> entry : selectionStats.entrySet()) {
-                list.add(new SegmentStoreStatisticsModel(getUniqueId(SELECTION_PREFIX + entry.getKey()), selectionId, entry.getKey(), entry.getValue()));
+                list.add(new SegmentStoreStatisticsModel(getUniqueId(SELECTION_PREFIX + entry.getKey()), selectionId, Collections.singletonList(entry.getKey()), entry.getValue()));
             }
         }
-        return new TmfModelResponse<>(Collections.unmodifiableList(list), Status.COMPLETED, CommonStatusMessage.COMPLETED);
+        return new TmfModelResponse<>(new TmfTreeModel<>(Collections.emptyList(), Collections.unmodifiableList(list)), Status.COMPLETED, CommonStatusMessage.COMPLETED);
     }
 
     private long getUniqueId(String name) {
diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/messages.properties b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/messages.properties
index f9de5ff..6bc2429 100644
--- a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/messages.properties
+++ b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/messages.properties
@@ -16,4 +16,6 @@
 SegmentStoreDataProvider_SegmentNotAvailable=Segment store is not available for this provider
 SegmentStoreStatisticsDataProvider_Selection=Selection
 SegmentStoreStatisticsDataProvider_Total=Total
-SegmentStoreStatisticsDataProviderFactory_AnalysisName=Generic Segment Statistics for {0}
\ No newline at end of file
+SegmentStoreStatisticsDataProviderFactory_AnalysisName=Generic Segment Statistics for {0}
+SegmentStoreScatterGraphDataProvider_title={0} - Latency vs Time
+SegmentStoreScatterGraphDataProvider_description=Show latencies provided by {0}
\ No newline at end of file
diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/analysis/timing/ui/views/segmentstore/statistics/AbstractSegmentsStatisticsViewer.java b/analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/analysis/timing/ui/views/segmentstore/statistics/AbstractSegmentsStatisticsViewer.java
index da3d363..865ef67 100644
--- a/analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/analysis/timing/ui/views/segmentstore/statistics/AbstractSegmentsStatisticsViewer.java
+++ b/analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/analysis/timing/ui/views/segmentstore/statistics/AbstractSegmentsStatisticsViewer.java
@@ -36,11 +36,13 @@
 import org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.SubSecondTimeWithUnitFormat;
 import org.eclipse.tracecompass.internal.analysis.timing.core.segmentstore.SegmentStoreStatisticsDataProvider;
 import org.eclipse.tracecompass.internal.analysis.timing.ui.views.segmentstore.statistics.Messages;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule;
 import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderManager;
 import org.eclipse.tracecompass.tmf.core.model.filters.FilterTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataProvider;
 import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeDataModel;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
@@ -273,13 +275,13 @@
         }
 
         FilterTimeQueryFilter filter = new FilterTimeQueryFilter(start, end, 2, isSelection);
-        TmfModelResponse<List<SegmentStoreStatisticsModel>> response = provider.fetchTree(filter, null);
-        List<SegmentStoreStatisticsModel> model = response.getModel();
+        TmfModelResponse<TmfTreeModel<SegmentStoreStatisticsModel>> response = provider.fetchTree(FetchParametersUtils.filteredTimeQueryToMap(filter), null);
+        TmfTreeModel<SegmentStoreStatisticsModel> model = response.getModel();
         if (model == null) {
             return null;
         }
 
-        return modelToTree(trace.getName(), model);
+        return modelToTree(trace.getName(), model.getEntries());
     }
 
     /**
diff --git a/ctf/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/histogram/dataprovider/HistogramDataProviderTest.java b/ctf/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/histogram/dataprovider/HistogramDataProviderTest.java
index dd828f7..b6c22c1 100644
--- a/ctf/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/histogram/dataprovider/HistogramDataProviderTest.java
+++ b/ctf/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/histogram/dataprovider/HistogramDataProviderTest.java
@@ -19,15 +19,16 @@
 import org.eclipse.core.runtime.Status;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.tracecompass.internal.tmf.core.histogram.HistogramDataProvider;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.testtraces.ctf.CtfTestTrace;
 import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
-import org.eclipse.tracecompass.tmf.core.model.YModel;
+import org.eclipse.tracecompass.tmf.core.model.SeriesModel;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeDataModel;
-import org.eclipse.tracecompass.tmf.core.model.xy.ITmfCommonXAxisModel;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
+import org.eclipse.tracecompass.tmf.core.model.xy.ISeriesModel;
 import org.eclipse.tracecompass.tmf.core.model.xy.ITmfXyModel;
-import org.eclipse.tracecompass.tmf.core.model.xy.IYModel;
 import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 import org.eclipse.tracecompass.tmf.core.statistics.TmfStatisticsModule;
@@ -51,13 +52,24 @@
     private static final long END = 1376592668452869400L;
 
     private static final List<String> EXPECTED_FULL_PATHS = ImmutableList.of("hello-lost", "hello-lost/Total", "hello-lost/Lost");
-    private static final Map<String, IYModel> EXPECTED_YDATA = ImmutableMap.of("hello-lost/Total",
-            new YModel(1, "hello-lost/Total",
+    private static final long @NonNull [] EXPECTED_COMMON_XDATA = new long[] {
+            1376592664828559410l, 1376592664865168602l, 1376592664901777794l, 1376592664938386985l, 1376592664974996177l, 1376592665011605369l, 1376592665048214561l, 1376592665084823753l, 1376592665121432945l, 1376592665158042136l,
+            1376592665194651328l, 1376592665231260520l, 1376592665267869712l, 1376592665304478904l, 1376592665341088095l, 1376592665377697287l, 1376592665414306479l, 1376592665450915671l, 1376592665487524863l, 1376592665524134055l,
+            1376592665560743246l, 1376592665597352438l, 1376592665633961630l, 1376592665670570822l, 1376592665707180014l, 1376592665743789205l, 1376592665780398397l, 1376592665817007589l, 1376592665853616781l, 1376592665890225973l,
+            1376592665926835165l, 1376592665963444356l, 1376592666000053548l, 1376592666036662740l, 1376592666073271932l, 1376592666109881124l, 1376592666146490315l, 1376592666183099507l, 1376592666219708699l, 1376592666256317891l,
+            1376592666292927083l, 1376592666329536275l, 1376592666366145466l, 1376592666402754658l, 1376592666439363850l, 1376592666475973042l, 1376592666512582234l, 1376592666549191425l, 1376592666585800617l, 1376592666622409809l,
+            1376592666659019001l, 1376592666695628193l, 1376592666732237385l, 1376592666768846576l, 1376592666805455768l, 1376592666842064960l, 1376592666878674152l, 1376592666915283344l, 1376592666951892535l, 1376592666988501727l,
+            1376592667025110919l, 1376592667061720111l, 1376592667098329303l, 1376592667134938495l, 1376592667171547686l, 1376592667208156878l, 1376592667244766070l, 1376592667281375262l, 1376592667317984454l, 1376592667354593645l,
+            1376592667391202837l, 1376592667427812029l, 1376592667464421221l, 1376592667501030413l, 1376592667537639605l, 1376592667574248796l, 1376592667610857988l, 1376592667647467180l, 1376592667684076372l, 1376592667720685564l,
+            1376592667757294755l, 1376592667793903947l, 1376592667830513139l, 1376592667867122331l, 1376592667903731523l, 1376592667940340715l, 1376592667976949906l, 1376592668013559098l, 1376592668050168290l, 1376592668086777482l,
+            1376592668123386674l, 1376592668159995865l, 1376592668196605057l, 1376592668233214249l, 1376592668269823441l, 1376592668306432633l, 1376592668343041825l, 1376592668379651016l, 1376592668416260208l, 1376592668452869400l };
+    private static final Map<String, ISeriesModel> EXPECTED_YDATA = ImmutableMap.of(Long.toString(1),
+            new SeriesModel(1, "hello-lost/Total", EXPECTED_COMMON_XDATA,
                     new double[] { 1.0, 1101.0, 342.0, 1520.0, 7182.0, 6802.0, 3002.0, 3616.0, 8734.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                             0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                             0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }),
-            "hello-lost/Lost",
-            new YModel(2, "hello-lost/Lost",
+            Long.toString(2),
+            new SeriesModel(2, "hello-lost/Lost", EXPECTED_COMMON_XDATA,
                     new double[] { 859.0, 91775.0, 152692.53033367038, 163867.2477369654, 144965.73090892372, 161976.6598828061, 168719.01789009458, 139270.93218317698, 1.4303668261140892, 1.4303668261140892, 1.4303668261140892,
                             1.4303668261140892, 1.4303668261140892, 1.4303668261140892, 1.4303668261140892, 1.4303668261140892, 1.4303668261140892, 1.4303668261140892, 1.4303668261140892, 1.4303668261140892, 1.4303668261140892, 1.4303668261140892,
                             1.4303668261140892, 1.4303668261140892, 1.4303668261140892, 1.4303668261140892, 1.4303668261140892, 1.4303668261140892, 1.4303668261140892, 1.4303668261140892, 1.4303668261140892, 1.4303668261140892, 1.4303668261140892,
@@ -86,22 +98,21 @@
         assertTrue("Statistics Analysis should run successfully", module.waitForCompletion());
         try {
             HistogramDataProvider provider = new HistogramDataProvider(trace, module);
-            TmfModelResponse<@NonNull List<@NonNull TmfTreeDataModel>> treeResponse = provider.fetchTree(new TimeQueryFilter(START, END, 2), null);
+            TmfModelResponse<@NonNull TmfTreeModel<@NonNull TmfTreeDataModel>> treeResponse = provider.fetchTree(FetchParametersUtils.timeQueryToMap(new TimeQueryFilter(START, END, 2)), null);
             assertEquals("Response Status should be COMPLETED, as we waited for the analysis to complete",
                     ITmfResponse.Status.COMPLETED, treeResponse.getStatus());
-            List<@NonNull TmfTreeDataModel> treeModel = treeResponse.getModel();
+            TmfTreeModel<@NonNull TmfTreeDataModel> treeModel = treeResponse.getModel();
             assertNotNull(treeModel);
-            assertEquals(EXPECTED_FULL_PATHS, getFullPaths(treeModel));
+            assertEquals(EXPECTED_FULL_PATHS, getFullPaths(treeModel.getEntries()));
 
-            List<Long> ids = Lists.transform(treeModel, TmfTreeDataModel::getId);
+            List<Long> ids = Lists.transform(treeModel.getEntries(), TmfTreeDataModel::getId);
             SelectionTimeQueryFilter selectionFilter = new SelectionTimeQueryFilter(START, END, 100, ids);
-            TmfModelResponse<@NonNull ITmfXyModel> xyResponse = provider.fetchXY(selectionFilter, null);
+            TmfModelResponse<@NonNull ITmfXyModel> xyResponse = provider.fetchXY(FetchParametersUtils.selectionTimeQueryToMap(selectionFilter), null);
             assertEquals("Response Status should be COMPLETED, as we waited for the analysis to complete",
                     ITmfResponse.Status.COMPLETED, xyResponse.getStatus());
             ITmfXyModel xyModel = xyResponse.getModel();
-            assertTrue(xyModel instanceof ITmfCommonXAxisModel);
-            ITmfCommonXAxisModel commonXModel = (ITmfCommonXAxisModel) xyModel;
-            assertEquals(EXPECTED_YDATA, commonXModel.getYData());
+            assertNotNull(xyModel);
+            assertEquals(EXPECTED_YDATA, xyModel.getData());
         } finally {
             module.dispose();
             CtfTmfTestTraceUtils.dispose(CtfTestTrace.HELLO_LOST);
diff --git a/lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/perf/org/eclipse/tracecompass/lttng2/kernel/core/tests/perf/analysis/cpu/CPUAnalysisBenchmark.java b/lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/perf/org/eclipse/tracecompass/lttng2/kernel/core/tests/perf/analysis/cpu/CPUAnalysisBenchmark.java
index 0c82039..fa6b70d 100644
--- a/lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/perf/org/eclipse/tracecompass/lttng2/kernel/core/tests/perf/analysis/cpu/CPUAnalysisBenchmark.java
+++ b/lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/perf/org/eclipse/tracecompass/lttng2/kernel/core/tests/perf/analysis/cpu/CPUAnalysisBenchmark.java
@@ -17,7 +17,9 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.commons.io.FileUtils;
 import org.eclipse.core.runtime.FileLocator;
@@ -35,10 +37,12 @@
 import org.eclipse.tracecompass.lttng2.kernel.core.trace.LttngKernelTrace;
 import org.eclipse.tracecompass.testtraces.ctf.CtfTestTrace;
 import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
+import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
 import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
 import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectedCpuQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.model.xy.ITmfXyModel;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
@@ -198,19 +202,31 @@
                 for (int j = 0; j < 10; j++) {
                     // Query the tree for that range
                     TimeQueryFilter filter = new SelectedCpuQueryFilter(startTime, endTime, 2, Collections.emptyList(), Collections.emptySet());
-                    TmfModelResponse<List<CpuUsageEntryModel>> response = dataProvider.fetchTree(filter, NULL_MONITOR);
-                    List<CpuUsageEntryModel> model = response.getModel();
+
+                    @NonNull Map<@NonNull String, @NonNull Object> parameters = new HashMap<>();
+                    parameters.put(DataProviderParameterUtils.REQUESTED_TIME_KEY, getTimeRequested(filter));
+                    parameters.put(DataProviderParameterUtils.REQUESTED_ITEMS_KEY, Collections.emptyList());
+                    parameters.put("cpus", Collections.emptySet());
+                    TmfModelResponse<@NonNull TmfTreeModel<@NonNull CpuUsageEntryModel>> response = dataProvider.fetchTree(parameters, NULL_MONITOR);
+                    TmfTreeModel<@NonNull CpuUsageEntryModel> model = response.getModel();
                     assertNotNull(model);
 
+                    List<CpuUsageEntryModel> entries = model.getEntries();
+                    assertNotNull(entries);
+
                     // Add all entries to the list of selected
                     List<Long> selected = new ArrayList<>();
-                    for (CpuUsageEntryModel entry : model) {
+                    for (CpuUsageEntryModel entry : entries) {
                         selected.add(entry.getId());
                     }
 
                     // Get the usage for all threads
                     filter = new SelectedCpuQueryFilter(startTime, endTime, resolution, selected, Collections.emptySet());
-                    TmfModelResponse<@NonNull ITmfXyModel> fetchXY = dataProvider.fetchXY(filter, NULL_MONITOR);
+                    parameters = new HashMap<>();
+                    parameters.put(DataProviderParameterUtils.REQUESTED_TIME_KEY, getTimeRequested(filter));
+                    parameters.put(DataProviderParameterUtils.REQUESTED_ITEMS_KEY, selected);
+                    parameters.put("cpus", Collections.emptySet());
+                    TmfModelResponse<@NonNull ITmfXyModel> fetchXY = dataProvider.fetchXY(parameters, NULL_MONITOR);
                     ITmfXyModel model2 = fetchXY.getModel();
                     assertNotNull(model2);
 
@@ -229,4 +245,12 @@
         pmAnalysisExecution.commit();
         pmQueryUsage.commit();
     }
+
+    private static @NonNull List<Long> getTimeRequested(TimeQueryFilter filter) {
+        List<Long> times = new ArrayList<>();
+        for (long time : filter.getTimesRequested()) {
+            times.add(time);
+        }
+        return times;
+    }
 }
diff --git a/lttng/org.eclipse.tracecompass.lttng2.ust.core/src/org/eclipse/tracecompass/internal/lttng2/ust/core/analysis/memory/Messages.java b/lttng/org.eclipse.tracecompass.lttng2.ust.core/src/org/eclipse/tracecompass/internal/lttng2/ust/core/analysis/memory/Messages.java
index 3d8e9e9..a6e31ec 100644
--- a/lttng/org.eclipse.tracecompass.lttng2.ust.core/src/org/eclipse/tracecompass/internal/lttng2/ust/core/analysis/memory/Messages.java
+++ b/lttng/org.eclipse.tracecompass.lttng2.ust.core/src/org/eclipse/tracecompass/internal/lttng2/ust/core/analysis/memory/Messages.java
@@ -28,12 +28,10 @@
 
     /** Example of how to execute the application with the libc wrapper */
     public static String UstMemoryAnalysisModule_EventsLoadingExampleInformation;
-
-    /**
-     * Chart title
-     */
+    /** Chart title */
     public static String MemoryUsageDataProvider_Title;
-
+    /** Data provider help text. */
+    public static String UstMemoryDataProviderFactory_DescriptionText;
     static {
         // initialize resource bundle
         NLS.initializeMessages(BUNDLE_NAME, Messages.class);
diff --git a/lttng/org.eclipse.tracecompass.lttng2.ust.core/src/org/eclipse/tracecompass/internal/lttng2/ust/core/analysis/memory/UstMemoryDataProviderFactory.java b/lttng/org.eclipse.tracecompass.lttng2.ust.core/src/org/eclipse/tracecompass/internal/lttng2/ust/core/analysis/memory/UstMemoryDataProviderFactory.java
index d16e384..caadab0 100644
--- a/lttng/org.eclipse.tracecompass.lttng2.ust.core/src/org/eclipse/tracecompass/internal/lttng2/ust/core/analysis/memory/UstMemoryDataProviderFactory.java
+++ b/lttng/org.eclipse.tracecompass.lttng2.ust.core/src/org/eclipse/tracecompass/internal/lttng2/ust/core/analysis/memory/UstMemoryDataProviderFactory.java
@@ -10,16 +10,24 @@
 package org.eclipse.tracecompass.internal.lttng2.ust.core.analysis.memory;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Objects;
 
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.internal.tmf.core.model.DataProviderDescriptor;
 import org.eclipse.tracecompass.internal.tmf.core.model.xy.TmfTreeXYCompositeDataProvider;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor.ProviderType;
 import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderFactory;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
 import org.eclipse.tracecompass.tmf.core.model.xy.ITmfTreeXYDataProvider;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
 
 /**
  * {@link UstMemoryUsageDataProvider} factory using the data provider factory
@@ -31,6 +39,14 @@
 public class UstMemoryDataProviderFactory implements IDataProviderFactory {
 
     private static final @NonNull String TITLE = Objects.requireNonNull(Messages.MemoryUsageDataProvider_Title);
+    private static final Predicate<? super ITmfTrace> PREDICATE = t -> TmfTraceUtils.getAnalysisModuleOfClass(t, UstMemoryAnalysisModule.class, UstMemoryAnalysisModule.ID) != null;
+
+    private static final IDataProviderDescriptor DESCRIPTOR = new DataProviderDescriptor.Builder()
+            .setId(UstMemoryAnalysisModule.ID)
+            .setName(Objects.requireNonNull(Messages.MemoryUsageDataProvider_Title))
+            .setDescription(Objects.requireNonNull(Messages.UstMemoryDataProviderFactory_DescriptionText))
+            .setProviderType(ProviderType.TREE_TIME_XY)
+            .build();
 
     /**
      * @since 4.0
@@ -45,4 +61,10 @@
         return TmfTreeXYCompositeDataProvider.create(traces, TITLE, UstMemoryUsageDataProvider.ID);
     }
 
+    @Override
+    public Collection<IDataProviderDescriptor> getDescriptors(@NonNull ITmfTrace trace) {
+        Collection<ITmfTrace> traces = TmfTraceManager.getTraceSet(trace);
+        return Iterables.any(traces, PREDICATE) ? Collections.singletonList(DESCRIPTOR) : Collections.emptyList();
+    }
+
 }
diff --git a/lttng/org.eclipse.tracecompass.lttng2.ust.core/src/org/eclipse/tracecompass/internal/lttng2/ust/core/analysis/memory/UstMemoryUsageDataProvider.java b/lttng/org.eclipse.tracecompass.lttng2.ust.core/src/org/eclipse/tracecompass/internal/lttng2/ust/core/analysis/memory/UstMemoryUsageDataProvider.java
index 09a6077..53579c7 100644
--- a/lttng/org.eclipse.tracecompass.lttng2.ust.core/src/org/eclipse/tracecompass/internal/lttng2/ust/core/analysis/memory/UstMemoryUsageDataProvider.java
+++ b/lttng/org.eclipse.tracecompass.lttng2.ust.core/src/org/eclipse/tracecompass/internal/lttng2/ust/core/analysis/memory/UstMemoryUsageDataProvider.java
@@ -21,14 +21,16 @@
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.analysis.os.linux.core.memory.MemoryUsageTreeModel;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.internal.tmf.core.model.xy.AbstractTreeCommonXDataProvider;
 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
 import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
 import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
 import org.eclipse.tracecompass.tmf.core.model.YModel;
-import org.eclipse.tracecompass.tmf.core.model.filters.FilterTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.model.xy.IYModel;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
@@ -82,7 +84,11 @@
      * @since 3.3
      */
     @Override
-    protected @Nullable Map<String, IYModel> getYModels(ITmfStateSystem ss, SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) throws StateSystemDisposedException {
+    protected @Nullable Map<String, IYModel> getYModels(ITmfStateSystem ss, Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) throws StateSystemDisposedException {
+        SelectionTimeQueryFilter filter = FetchParametersUtils.createSelectionTimeQuery(fetchParameters);
+        if (filter == null) {
+            return null;
+        }
         long[] xValues = filter.getTimesRequested();
         long currentEnd = ss.getCurrentEndTime();
 
@@ -137,21 +143,26 @@
      * @since 3.3
      */
     @Override
-    protected List<MemoryUsageTreeModel> getTree(ITmfStateSystem ss, TimeQueryFilter filter, @Nullable IProgressMonitor monitor)
+    protected TmfTreeModel<MemoryUsageTreeModel> getTree(ITmfStateSystem ss, Map<String, Object> parameters, @Nullable IProgressMonitor monitor)
             throws StateSystemDisposedException {
 
+        TimeQueryFilter filter = FetchParametersUtils.createTimeQuery(parameters);
+        if (filter == null) {
+            return new TmfTreeModel<>(Collections.emptyList(), Collections.emptyList());
+        }
         long start = filter.getStart();
         long end = filter.getEnd();
 
         // Let the list of active states be null if we aren't filtering
         List<ITmfStateInterval> active = null;
-        if (filter instanceof FilterTimeQueryFilter && ((FilterTimeQueryFilter) filter).isFiltered()) {
+        Boolean isFiltered = DataProviderParameterUtils.extractIsFiltered(parameters);
+        if (isFiltered != null && isFiltered) {
             if (start == end || start > ss.getCurrentEndTime() || end < ss.getStartTime()) {
                 /*
                  * return an empty list if the filter is empty or does not intersect the state
                  * system
                  */
-                return Collections.emptyList();
+                return new TmfTreeModel<>(Collections.emptyList(), Collections.emptyList());
             }
             active = ss.queryFullState(Long.max(start, ss.getStartTime()));
         }
@@ -161,7 +172,7 @@
 
         ImmutableList.Builder<MemoryUsageTreeModel> builder = ImmutableList.builder();
         long rootId = getId(ITmfStateSystem.ROOT_ATTRIBUTE);
-        builder.add(new MemoryUsageTreeModel(rootId, -1L, -1, getTrace().getName()));
+        builder.add(new MemoryUsageTreeModel(rootId, -1L, -1, Collections.singletonList(getTrace().getName())));
         for (int quark : tidQuarks) {
             int memoryAttribute = ss.optQuarkRelative(quark, UstMemoryStrings.UST_MEMORY_MEMORY_ATTRIBUTE);
             int procNameQuark = ss.optQuarkRelative(quark, UstMemoryStrings.UST_MEMORY_PROCNAME_ATTRIBUTE);
@@ -175,11 +186,11 @@
                     && (active == null || (memoryAttribute < active.size() && active.get(memoryAttribute).getEndTime() < end))) {
 
                 int tid = Integer.parseInt(ss.getAttributeName(quark));
-                builder.add(new MemoryUsageTreeModel(getId(quark), rootId, tid, name));
+                builder.add(new MemoryUsageTreeModel(getId(quark), rootId, tid, Collections.singletonList(name)));
             }
         }
 
-        return builder.build();
+        return new TmfTreeModel<>(Collections.emptyList(), builder.build());
     }
 
     /**
diff --git a/lttng/org.eclipse.tracecompass.lttng2.ust.core/src/org/eclipse/tracecompass/internal/lttng2/ust/core/analysis/memory/messages.properties b/lttng/org.eclipse.tracecompass.lttng2.ust.core/src/org/eclipse/tracecompass/internal/lttng2/ust/core/analysis/memory/messages.properties
index 08074e6..36d96fa 100644
--- a/lttng/org.eclipse.tracecompass.lttng2.ust.core/src/org/eclipse/tracecompass/internal/lttng2/ust/core/analysis/memory/messages.properties
+++ b/lttng/org.eclipse.tracecompass.lttng2.ust.core/src/org/eclipse/tracecompass/internal/lttng2/ust/core/analysis/memory/messages.properties
@@ -12,4 +12,5 @@
 UstMemoryAnalysisModule_EventsLoadingInformation=The libc wrapper should be loaded in order to get the events in the trace output.
 UstMemoryAnalysisModule_EventsLoadingExampleInformation=Start the application to trace with: LD_PRELOAD=/path/to/liblttng-ust-libc-wrapper.so ./myProgram.
 MemoryUsageDataProvider_Title=Memory Usage
+UstMemoryDataProviderFactory_DescriptionText=Show the Linux UST memory usage by thread, can be filtered to show only the threads which were active on a desired time range
 SegmentAspectHelpText_PotentialLeakTid=The ID of the thread to which this unfreed memory belongs
\ No newline at end of file
diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/module/XmlTimeGraphDataProviderTest.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/module/XmlTimeGraphDataProviderTest.java
index dfea27c..a49ab75 100644
--- a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/module/XmlTimeGraphDataProviderTest.java
+++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/module/XmlTimeGraphDataProviderTest.java
@@ -33,6 +33,7 @@
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.output.DataDrivenTimeGraphDataProvider;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.output.DataDrivenTimeGraphProviderFactory;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.output.XmlDataProviderManager;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
 import org.eclipse.tracecompass.tmf.analysis.xml.core.module.TmfXmlStrings;
 import org.eclipse.tracecompass.tmf.analysis.xml.core.module.TmfXmlUtils;
@@ -44,6 +45,8 @@
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphRowModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphState;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphEntryModel;
+import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphModel;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal;
@@ -146,11 +149,12 @@
     }
 
     private static void assertRows(ITimeGraphDataProvider<@NonNull TimeGraphEntryModel> provider, Map<Long, String> tree, List<String> expectedStrings) {
-        TmfModelResponse<List<ITimeGraphRowModel>> rowResponse = provider.fetchRowModel(new SelectionTimeQueryFilter(1, 20, 20, tree.keySet()), null);
+        TmfModelResponse<@NonNull TimeGraphModel> rowResponse = provider.fetchRowModel(FetchParametersUtils.selectionTimeQueryToMap(new SelectionTimeQueryFilter(1, 20, 20, tree.keySet())), null);
         assertNotNull(rowResponse);
         assertEquals(ITmfResponse.Status.COMPLETED, rowResponse.getStatus());
-        List<ITimeGraphRowModel> rowModel = rowResponse.getModel();
-        assertNotNull(rowModel);
+        TimeGraphModel timeGraphModel = rowResponse.getModel();
+        assertNotNull(timeGraphModel);
+        List<@NonNull ITimeGraphRowModel> rowModel = timeGraphModel.getRows();
         // ensure row order
         rowModel.sort(Comparator.comparingLong(ITimeGraphRowModel::getEntryID));
 
@@ -181,19 +185,20 @@
     }
 
     private static Map<Long, String> assertAndGetTree(ITimeGraphDataProvider<@NonNull TimeGraphEntryModel> timeGraphProvider, ITmfTrace trace, List<String> expectedStrings) {
-        TmfModelResponse<@NonNull List<@NonNull TimeGraphEntryModel>> treeResponse = timeGraphProvider.fetchTree(new TimeQueryFilter(0, Long.MAX_VALUE, 2), MONITOR);
+        TmfModelResponse<@NonNull TmfTreeModel<@NonNull TimeGraphEntryModel>> treeResponse = timeGraphProvider.fetchTree(FetchParametersUtils.timeQueryToMap(new TimeQueryFilter(0, Long.MAX_VALUE, 2)), MONITOR);
         assertNotNull(treeResponse);
         assertEquals(ITmfResponse.Status.COMPLETED, treeResponse.getStatus());
-        List<TimeGraphEntryModel> treeModel = treeResponse.getModel();
+        TmfTreeModel<@NonNull TimeGraphEntryModel> treeModel = treeResponse.getModel();
         assertNotNull(treeModel);
+        List<@NonNull TimeGraphEntryModel> xmlEntries = treeModel.getEntries();
 
-        Collections.sort(treeModel, Comparator.comparingLong(TimeGraphEntryModel::getId));
+        Collections.sort(xmlEntries, Comparator.comparingLong(TimeGraphEntryModel::getId));
         Map<Long, String> map = new HashMap<>();
         for (int i = 0; i < expectedStrings.size(); i++) {
             String expectedString = expectedStrings.get(i);
-            assertTrue("actual entry present at " + i + ": " + expectedString, treeModel.size() > i);
+            assertTrue("actual entry present at " + i + ": " + expectedString, xmlEntries.size() > i);
             String[] split = expectedString.split(",");
-            TimeGraphEntryModel xmlTgEntry = treeModel.get(i);
+            TimeGraphEntryModel xmlTgEntry = xmlEntries.get(i);
 
             assertEquals("Checking entry name at " + i, split[0], xmlTgEntry.getName());
             assertEquals("Checking entry start time at " + i, Long.parseLong(split[1]), xmlTgEntry.getStartTime());
@@ -208,7 +213,7 @@
             }
             map.put(xmlTgEntry.getId(), xmlTgEntry.getName());
         }
-        assertEquals("Extra actual entries", expectedStrings.size(), treeModel.size());
+        assertEquals("Extra actual entries", expectedStrings.size(), xmlEntries.size());
 
         return map;
     }
diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/module/XmlXyDataProviderTest.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/module/XmlXyDataProviderTest.java
index 424f8ad..d221a8e 100644
--- a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/module/XmlXyDataProviderTest.java
+++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/module/XmlXyDataProviderTest.java
@@ -19,6 +19,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.NullProgressMonitor;
@@ -26,6 +27,7 @@
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.module.XmlAnalysisModuleSource;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.module.XmlUtils;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.output.XmlDataProviderManager;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.tmf.analysis.xml.core.module.TmfXmlStrings;
 import org.eclipse.tracecompass.tmf.analysis.xml.core.module.TmfXmlUtils;
 import org.eclipse.tracecompass.tmf.analysis.xml.core.tests.common.TmfXmlTestFiles;
@@ -33,6 +35,7 @@
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.model.xy.ISeriesModel;
 import org.eclipse.tracecompass.tmf.core.model.xy.ITmfTreeXYDataProvider;
 import org.eclipse.tracecompass.tmf.core.model.xy.ITmfXyModel;
@@ -166,7 +169,7 @@
     }
 
     private static void assertRows(ITmfTreeXYDataProvider<@NonNull ITmfTreeDataModel> xyProvider, Map<Long, String> tree, List<String> expectedStrings) {
-        TmfModelResponse<@NonNull ITmfXyModel> rowResponse = xyProvider.fetchXY(new SelectionTimeQueryFilter(1, 20, 20, tree.keySet()), null);
+        TmfModelResponse<@NonNull ITmfXyModel> rowResponse = xyProvider.fetchXY(FetchParametersUtils.selectionTimeQueryToMap(new SelectionTimeQueryFilter(1, 20, 20, tree.keySet())), null);
         assertNotNull(rowResponse);
         assertEquals(ITmfResponse.Status.COMPLETED, rowResponse.getStatus());
         ITmfXyModel rowModel = rowResponse.getModel();
@@ -177,7 +180,15 @@
             String expectedString = expectedStrings.get(i);
             String[] split = expectedString.split(":");
             String rowName = split[0];
-            ISeriesModel row = data.get(rowName);
+            String rowId = null;
+            for (Entry<Long, String> entry : tree.entrySet()) {
+                if (entry.getValue().equals(rowName)) {
+                    rowId = Long.toString(entry.getKey());
+                    break;
+                }
+            }
+            assertNotNull(rowId);
+            ISeriesModel row = data.get(rowId);
             assertNotNull(row);
 
             String[] expectedData = split[1].split(",");
@@ -194,18 +205,19 @@
     }
 
     private static Map<Long, String> assertAndGetTree(ITmfTreeXYDataProvider<@NonNull ITmfTreeDataModel> xyProvider, ITmfTrace trace, List<String> expectedStrings) {
-        TmfModelResponse<@NonNull List<ITmfTreeDataModel>> treeResponse = xyProvider.fetchTree(new TimeQueryFilter(0, Long.MAX_VALUE, 2), MONITOR);
+        TmfModelResponse<@NonNull TmfTreeModel<@NonNull ITmfTreeDataModel>> treeResponse = xyProvider.fetchTree(FetchParametersUtils.timeQueryToMap(new TimeQueryFilter(0, Long.MAX_VALUE, 2)), MONITOR);
         assertNotNull(treeResponse);
         assertEquals(ITmfResponse.Status.COMPLETED, treeResponse.getStatus());
-        List<ITmfTreeDataModel> treeModel = treeResponse.getModel();
+        TmfTreeModel<@NonNull ITmfTreeDataModel> treeModel = treeResponse.getModel();
         assertNotNull(treeModel);
+        List<@NonNull ITmfTreeDataModel> treeEntries = treeModel.getEntries();
 
         Map<Long, String> map = new HashMap<>();
         for (int i = 0; i < expectedStrings.size(); i++) {
             String expectedString = expectedStrings.get(i);
-            assertTrue("actual entry absent at " + i + ": " + expectedString, treeModel.size() > i);
+            assertTrue("actual entry absent at " + i + ": " + expectedString, treeEntries.size() > i);
             String[] split = expectedString.split(",");
-            ITmfTreeDataModel xmlXyEntry = treeModel.get(i);
+            ITmfTreeDataModel xmlXyEntry = treeEntries.get(i);
 
             assertEquals("Checking entry name at " + i, split[0], xmlXyEntry.getName());
             // Check the parent
@@ -218,7 +230,7 @@
             }
             map.put(xmlXyEntry.getId(), xmlXyEntry.getName());
         }
-        assertEquals("Extra actual entries", expectedStrings.size(), treeModel.size());
+        assertEquals("Extra actual entries", expectedStrings.size(), treeEntries.size());
 
         return map;
     }
diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/XmlTimeGraphDataProvider.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/XmlTimeGraphDataProvider.java
index 542b0fa..4f6eb5a 100644
--- a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/XmlTimeGraphDataProvider.java
+++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/XmlTimeGraphDataProvider.java
@@ -35,7 +35,7 @@
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.fsm.model.DataDrivenStateSystemPath;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.module.XmlTimeGraphEntryModel.Builder;
 import org.eclipse.tracecompass.internal.tmf.core.model.AbstractTmfTraceDataProvider;
-import org.eclipse.tracecompass.internal.tmf.core.model.filters.TimeGraphStateQueryFilter;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
 import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
 import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
@@ -43,6 +43,7 @@
 import org.eclipse.tracecompass.tmf.analysis.xml.core.module.TmfXmlStrings;
 import org.eclipse.tracecompass.tmf.analysis.xml.core.module.TmfXmlUtils;
 import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
+import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
 import org.eclipse.tracecompass.tmf.core.model.CommonStatusMessage;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
@@ -50,8 +51,11 @@
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphDataProvider;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphRowModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphState;
+import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphRowModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphState;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
+import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
 import org.eclipse.tracecompass.tmf.core.response.ITmfResponse.Status;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 import org.eclipse.tracecompass.tmf.core.statesystem.ITmfAnalysisModuleWithStateSystems;
@@ -141,8 +145,8 @@
     }
 
     @Override
-    public TmfModelResponse<@NonNull List<XmlTimeGraphEntryModel>> fetchTree(@NonNull TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
-        List<XmlTimeGraphEntryModel> entryList = new ArrayList<>();
+    public TmfModelResponse<TmfTreeModel<@NonNull XmlTimeGraphEntryModel>> fetchTree(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
+        @NonNull List<@NonNull XmlTimeGraphEntryModel> entryList = new ArrayList<>();
         boolean isComplete = true;
 
         String traceName = String.valueOf(getTrace().getName());
@@ -153,7 +157,7 @@
                 long start = ss.getStartTime();
                 long end = ss.getCurrentEndTime();
                 long id = fBaseQuarkToId.row(ss).computeIfAbsent(ITmfStateSystem.ROOT_ATTRIBUTE, s -> sfAtomicId.getAndIncrement());
-                Builder ssEntry = new Builder(id, -1, traceName, start, end, null, ss, ITmfStateSystem.ROOT_ATTRIBUTE, fCompilationData);
+                Builder ssEntry = new Builder(id, -1, Collections.singletonList(traceName), start, end, null, ss, ITmfStateSystem.ROOT_ATTRIBUTE, fCompilationData);
                 entryList.add(ssEntry.build());
 
                 for (Element entry : fEntries) {
@@ -163,7 +167,7 @@
         }
         Status status = isComplete ? Status.COMPLETED : Status.RUNNING;
         String msg = isComplete ? CommonStatusMessage.COMPLETED : CommonStatusMessage.RUNNING;
-        return new TmfModelResponse<>(entryList, status, msg);
+        return new TmfModelResponse<>(new TmfTreeModel<>(Collections.emptyList(), entryList), status, msg);
     }
 
     private void buildEntry(ITmfStateSystem ssq, Element entryElement, @NonNull Builder parentEntry,
@@ -246,7 +250,7 @@
             } else {
                 long id = fBaseQuarkToId.row(ss).computeIfAbsent(quark, s -> sfAtomicId.getAndIncrement());
                 currentEntry =  new Builder(id, parentEntry.getId(),
-                        ss.getAttributeName(quark), ss.getStartTime(), ss.getCurrentEndTime(), null, ss, quark, fCompilationData);
+                        Collections.singletonList(ss.getAttributeName(quark)), ss.getStartTime(), ss.getCurrentEndTime(), null, ss, quark, fCompilationData);
                 entryMap.put(currentEntry.getXmlId(), currentEntry);
             }
             /* Process the children entry of this entry */
@@ -271,7 +275,7 @@
         long id = fBaseQuarkToId.row(ss).computeIfAbsent(quark, s -> sfAtomicId.getAndIncrement());
         if (displayQuark < 0) {
             return new Builder(id, parentEntry.getId(),
-                    String.format("Unknown display quark for %s", ss.getAttributeName(quark)), ss.getStartTime(), ss.getCurrentEndTime(), null, ss, quark, fCompilationData); //$NON-NLS-1$
+                    Collections.singletonList(String.format("Unknown display quark for %s", ss.getAttributeName(quark))), ss.getStartTime(), ss.getCurrentEndTime(), null, ss, quark, fCompilationData); //$NON-NLS-1$
         }
         fIDToDisplayQuark.put(id, new Pair<>(ss, displayQuark));
 
@@ -305,7 +309,7 @@
         } catch (StateSystemDisposedException e) {
         }
 
-        return new Builder(id, parentEntry.getId(), ss.getAttributeName(quark), entryStart, entryEnd, entryElement, ss, quark, fCompilationData);
+        return new Builder(id, parentEntry.getId(), Collections.singletonList(ss.getAttributeName(quark)), entryStart, entryEnd, entryElement, ss, quark, fCompilationData);
     }
 
     /** Build a tree using getParentId() and getId() */
@@ -340,8 +344,17 @@
     }
 
     @Override
-    public @NonNull TmfModelResponse<@NonNull List<@NonNull ITimeGraphRowModel>> fetchRowModel(@NonNull SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public @NonNull TmfModelResponse<@NonNull TimeGraphModel> fetchRowModel(@NonNull Map<@NonNull String, @NonNull Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         Table<ITmfStateSystem, Integer, Long> table = HashBasedTable.create();
+
+        // TODO server: Parameters validation should be handle separately. It
+        // can be either in the data provider itself or before calling it. It
+        // will avoid the creation of filters and the content of the map can be
+        // use directly.
+        SelectionTimeQueryFilter filter = FetchParametersUtils.createSelectionTimeQuery(fetchParameters);
+        if (filter == null) {
+            return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, CommonStatusMessage.INCORRECT_QUERY_PARAMETERS);
+        }
         for (Long id : filter.getSelectedItems()) {
             Pair<ITmfStateSystem, Integer> pair = fIDToDisplayQuark.get(id);
             if (pair != null) {
@@ -351,21 +364,21 @@
         List<@NonNull ITimeGraphRowModel> allRows = new ArrayList<>();
         try {
             for (Entry<ITmfStateSystem, Map<Integer, Long>> ssEntry : table.rowMap().entrySet()) {
-                Collection<@NonNull ITimeGraphRowModel> rows = createRows(ssEntry.getKey(), ssEntry.getValue(), filter.getTimesRequested(), filter, monitor);
+                Collection<@NonNull ITimeGraphRowModel> rows = createRows(ssEntry.getKey(), ssEntry.getValue(), filter.getTimesRequested(), fetchParameters, monitor);
                 allRows.addAll(rows);
             }
         } catch (IndexOutOfBoundsException | TimeRangeException | StateSystemDisposedException e) {
             return new TmfModelResponse<>(null, Status.FAILED, CommonStatusMessage.STATE_SYSTEM_FAILED);
         }
-        return new TmfModelResponse<>(allRows, Status.COMPLETED, CommonStatusMessage.COMPLETED);
+        return new TmfModelResponse<>(new TimeGraphModel(allRows), Status.COMPLETED, CommonStatusMessage.COMPLETED);
     }
 
     private @NonNull Collection<@NonNull ITimeGraphRowModel> createRows(ITmfStateSystem ss, Map<Integer, Long> idToDisplayQuark,
-            long[] timesRequested, SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) throws StateSystemDisposedException {
+            long[] timesRequested, @NonNull Map<@NonNull String, @NonNull Object> parameters, @Nullable IProgressMonitor monitor) throws StateSystemDisposedException {
         Map<@NonNull Integer, @NonNull Predicate<@NonNull Multimap<@NonNull String, @NonNull String>>> predicates = new HashMap<>();
-        if (filter instanceof TimeGraphStateQueryFilter) {
-            TimeGraphStateQueryFilter timeEventFilter = (TimeGraphStateQueryFilter) filter;
-            predicates.putAll(computeRegexPredicate(timeEventFilter));
+        Multimap<@NonNull Integer, @NonNull String> regexesMap = DataProviderParameterUtils.extractRegexFilter(parameters);
+        if (regexesMap != null) {
+            predicates.putAll(computeRegexPredicate(regexesMap));
         }
 
         long currentEndTime = ss.getCurrentEndTime();
@@ -418,13 +431,53 @@
     }
 
     @Override
-    public @NonNull TmfModelResponse<@NonNull List<@NonNull ITimeGraphArrow>> fetchArrows(@NonNull TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public @NonNull TmfModelResponse<@NonNull List<@NonNull ITimeGraphArrow>> fetchArrows(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         return new TmfModelResponse<>(null, Status.COMPLETED, CommonStatusMessage.COMPLETED);
     }
 
     @Override
-    public @NonNull TmfModelResponse<@NonNull Map<@NonNull String, @NonNull String>> fetchTooltip(@NonNull SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public @NonNull TmfModelResponse<@NonNull Map<@NonNull String, @NonNull String>> fetchTooltip(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         return new TmfModelResponse<>(null, Status.COMPLETED, CommonStatusMessage.COMPLETED);
     }
 
+    @Deprecated
+    @Override
+    public TmfModelResponse<List<XmlTimeGraphEntryModel>> fetchTree(@NonNull TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        @NonNull Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        TmfModelResponse<TmfTreeModel<@NonNull XmlTimeGraphEntryModel>> response = fetchTree(parameters, monitor);
+        TmfTreeModel<@NonNull XmlTimeGraphEntryModel> model = response.getModel();
+        List<XmlTimeGraphEntryModel> treeModel = null;
+        if (model != null) {
+            treeModel = model.getEntries();
+        }
+        return new TmfModelResponse<>(treeModel, response.getStatus(), response.getStatusMessage());
+    }
+
+    @Deprecated
+    @Override
+    public @NonNull TmfModelResponse<@NonNull List<@NonNull ITimeGraphRowModel>> fetchRowModel(@NonNull SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        @NonNull Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.selectionTimeQueryToMap(filter);
+        TmfModelResponse<@NonNull TimeGraphModel> response = fetchRowModel(parameters, monitor);
+        TimeGraphModel model = response.getModel();
+        List<@NonNull ITimeGraphRowModel> rows = null;
+        if (model != null) {
+            rows = model.getRows();
+        }
+        return new TmfModelResponse<>(rows, response.getStatus(), response.getStatusMessage());
+    }
+
+    @Deprecated
+    @Override
+    public @NonNull TmfModelResponse<@NonNull List<@NonNull ITimeGraphArrow>> fetchArrows(@NonNull TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        Map<String, Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        return fetchArrows(parameters, monitor);
+    }
+
+    @Deprecated
+    @Override
+    public @NonNull TmfModelResponse<@NonNull Map<@NonNull String, @NonNull String>> fetchTooltip(@NonNull SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        Map<String, Object> parameters = FetchParametersUtils.selectionTimeQueryToMap(filter);
+        return fetchTooltip(parameters, monitor);
+    }
+
 }
diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/XmlTimeGraphEntryModel.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/XmlTimeGraphEntryModel.java
index 4f42ed7..15bf684 100644
--- a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/XmlTimeGraphEntryModel.java
+++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/XmlTimeGraphEntryModel.java
@@ -48,7 +48,7 @@
 
         private final long fId;
         private long fParentId;
-        private String fName = EMPTY_STRING;
+        private @NonNull List<@NonNull String> fLabels = Collections.singletonList(EMPTY_STRING);
         private final long fStart;
         private final long fEnd;
         private final @Nullable Element fElement;
@@ -64,7 +64,7 @@
          *            unique entry model id
          * @param parentId
          *            parent's unique entry model id
-         * @param name
+         * @param labels
          *            default entry name
          * @param entryStart
          *            entry start time
@@ -79,11 +79,11 @@
          * @param data
          *            The compilation data that comes with this entry
          */
-        public Builder(long id, long parentId, @NonNull String name, long entryStart, long entryEnd,
+        public Builder(long id, long parentId, @NonNull List<@NonNull String> labels, long entryStart, long entryEnd,
                 @Nullable Element entryElement, @NonNull ITmfStateSystem ss, int baseQuark, @NonNull AnalysisCompilationData data) {
             fId = id;
             fParentId = parentId;
-            fName = name;
+            fLabels = labels;
             fStart = entryStart;
             fEnd = entryEnd;
             fElement = entryElement;
@@ -102,7 +102,7 @@
                 if (!elements.isEmpty()) {
                     String nameFromSs = getFirstValue(baseQuark, Objects.requireNonNull(elements.get(0)));
                     if (!nameFromSs.isEmpty()) {
-                        fName = nameFromSs;
+                        fLabels = Collections.singletonList(nameFromSs);
                     }
                 }
 
@@ -111,7 +111,7 @@
                 if (!elements.isEmpty()) {
                     fXmlId = getFirstValue(baseQuark, Objects.requireNonNull(elements.get(0)));
                 } else {
-                    fXmlId = name;
+                    fXmlId = labels.get(0);
                 }
             }
         }
@@ -146,7 +146,12 @@
 
         @Override
         public @NonNull String getName() {
-            return fName;
+            return fLabels.isEmpty() ? "" : fLabels.get(0); //$NON-NLS-1$
+        }
+
+        @Override
+        public @NonNull List<@NonNull String> getLabels() {
+            return fLabels;
         }
 
         @Override
@@ -202,7 +207,7 @@
          *
          * @return a new {@link XmlTimeGraphEntryModel} instance.
          */
-        public XmlTimeGraphEntryModel build() {
+        public @NonNull XmlTimeGraphEntryModel build() {
             Element element = fElement;
             boolean showText = false;
             String path = null;
@@ -210,7 +215,7 @@
                 showText = Boolean.parseBoolean(element.getAttribute(TmfXmlStrings.DISPLAY_TEXT));
                 path = element.getAttribute(TmfXmlStrings.PATH);
             }
-            return new XmlTimeGraphEntryModel(fId, fParentId, String.valueOf(fName), fStart, fEnd, path, fXmlId, fXmlParentId, showText);
+            return new XmlTimeGraphEntryModel(fId, fParentId, fLabels, fStart, fEnd, path, fXmlId, fXmlParentId, showText);
         }
 
         @Override
@@ -220,7 +225,7 @@
 
         @Override
         public String toString() {
-            return fName + " - " + fXmlId + " - " + fXmlParentId + " - " + fId + " - " + fParentId; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+            return fLabels + " - " + fXmlId + " - " + fXmlParentId + " - " + fId + " - " + fParentId; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
         }
 
     }
@@ -246,9 +251,9 @@
      *            entry end time
      * @return new instance
      */
-    public static XmlTimeGraphEntryModel create(long id, long parentId, @NonNull String name, long start, long end) {
+    public static XmlTimeGraphEntryModel create(long id, long parentId, @NonNull List<@NonNull String> name, long start, long end) {
         return new XmlTimeGraphEntryModel(id, parentId, name, start, end,
-                null, name, EMPTY_STRING, false);
+                null, name.get(0), EMPTY_STRING, false);
     }
 
     /**
@@ -256,8 +261,8 @@
      *            unique entry model id
      * @param parentId
      *            parent's unique entry model id
-     * @param name
-     *            default entry name
+     * @param labels
+     *            default entry labels
      * @param startTime
      *            entry start time
      * @param endTime
@@ -271,9 +276,9 @@
      * @param showText
      *            if the text should be shown for this entry or not.
      */
-    public XmlTimeGraphEntryModel(long id, long parentId, @NonNull String name, long startTime, long endTime,
+    public XmlTimeGraphEntryModel(long id, long parentId, @NonNull List<@NonNull String> labels, long startTime, long endTime,
             String path, @NonNull String xmlId, @NonNull String xmlParentId, boolean showText) {
-        super(id, parentId, name, startTime, endTime);
+        super(id, parentId, labels, startTime, endTime);
         fPath = path;
         fXmlId = xmlId;
         fXmlParentId = xmlParentId;
diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/XmlXYDataProvider.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/XmlXYDataProvider.java
index 1f998fd..e1ca103 100644
--- a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/XmlXYDataProvider.java
+++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/XmlXYDataProvider.java
@@ -32,6 +32,7 @@
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.fsm.model.DataDrivenStateSystemPath;
 import org.eclipse.tracecompass.internal.tmf.core.model.AbstractTmfTraceDataProvider;
 import org.eclipse.tracecompass.internal.tmf.core.model.TmfXyResponseFactory;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
 import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
 import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
@@ -43,6 +44,7 @@
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
 import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeDataModel;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.model.xy.ITmfTreeXYDataProvider;
 import org.eclipse.tracecompass.tmf.core.model.xy.ITmfXyModel;
 import org.eclipse.tracecompass.tmf.core.model.xy.IYModel;
@@ -88,7 +90,7 @@
     private final BiMap<Long, Integer> fIdToQuark = HashBiMap.create();
     private final BiMap<Integer, String> fQuarkToString = HashBiMap.create();
     private final long fTraceId = ENTRY_IDS.getAndIncrement();
-    private @Nullable TmfModelResponse<List<ITmfTreeDataModel>> fCached;
+    private @Nullable TmfModelResponse<TmfTreeModel<ITmfTreeDataModel>> fCached;
 
     private static class XmlXYEntry implements IXmlStateSystemContainer {
 
@@ -229,13 +231,17 @@
     }
 
     @Override
-    public TmfModelResponse<ITmfXyModel> fetchXY(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public TmfModelResponse<ITmfXyModel> fetchXY(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         DataDrivenStateSystemPath display = fDisplay;
         XmlXYEntry entry = fXmlEntry;
         ITmfStateSystem ss = entry.getStateSystem();
 
+        TimeQueryFilter filter = FetchParametersUtils.createTimeQuery(fetchParameters);
+        if (filter == null) {
+            return TmfXyResponseFactory.createFailedResponse(CommonStatusMessage.INCORRECT_QUERY_PARAMETERS);
+        }
         long[] xValues = filter.getTimesRequested();
-        Map<Integer, IYModel> map = initSeries(filter);
+        Map<Integer, IYModel> map = initSeries(fetchParameters);
         if (map.isEmpty()) {
             return TmfXyResponseFactory.create(TITLE, xValues, Collections.emptyMap(), true);
         }
@@ -272,7 +278,29 @@
         }
 
         boolean complete = ss.waitUntilBuilt(0) || filter.getEnd() <= currentEnd;
-        return TmfXyResponseFactory.create(TITLE, xValues, Maps.uniqueIndex(map.values(), IYModel::getName), complete);
+        return TmfXyResponseFactory.create(TITLE, xValues, Maps.uniqueIndex(map.values(), yModel -> Long.toString(yModel.getId())), complete);
+    }
+
+    private Map<Integer, IYModel> initSeries(Map<String, Object> parameters) {
+        SelectionTimeQueryFilter filter = FetchParametersUtils.createSelectionTimeQuery(parameters);
+        if (filter == null) {
+            return Collections.emptyMap();
+        }
+        fLock.readLock().lock();
+        try {
+            Map<Integer, IYModel> map = new HashMap<>();
+            int length = filter.getTimesRequested().length;
+            for (Long id : filter.getSelectedItems()) {
+                Integer quark = fIdToQuark.get(id);
+                if (quark != null) {
+                    String name = String.valueOf(fQuarkToString.get(quark));
+                    map.put(quark, new YModel(id, name, new double[length]));
+                }
+            }
+            return map;
+        } finally {
+            fLock.readLock().unlock();
+        }
     }
 
     private static void getSeriesDelta(double[] data) {
@@ -286,28 +314,6 @@
         }
         data[0] = data[1];
     }
-
-    private Map<Integer, IYModel> initSeries(TimeQueryFilter filter) {
-        if (!(filter instanceof SelectionTimeQueryFilter)) {
-            return Collections.emptyMap();
-        }
-        fLock.readLock().lock();
-        try {
-            Map<Integer, IYModel> map = new HashMap<>();
-            int length = filter.getTimesRequested().length;
-            for (Long id : ((SelectionTimeQueryFilter) filter).getSelectedItems()) {
-                Integer quark = fIdToQuark.get(id);
-                if (quark != null) {
-                    String name = String.valueOf(fQuarkToString.get(quark));
-                    map.put(quark, new YModel(id, name, new double[length]));
-                }
-            }
-            return map;
-        } finally {
-            fLock.readLock().unlock();
-        }
-    }
-
     private static double extractValue(@Nullable Object val) {
         if (val instanceof Number) {
             return ((Number) val).doubleValue();
@@ -339,7 +345,7 @@
      * @since 2.4
      */
     @Override
-    public TmfModelResponse<List<ITmfTreeDataModel>> fetchTree(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public TmfModelResponse<TmfTreeModel<ITmfTreeDataModel>> fetchTree(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         fLock.readLock().lock();
         try {
             if (fCached != null) {
@@ -359,7 +365,7 @@
         try {
             List<ITmfStateInterval> fullState = ss.queryFullState(ss.getCurrentEndTime());
             ImmutableList.Builder<ITmfTreeDataModel> builder = ImmutableList.builder();
-            builder.add(new TmfTreeDataModel(fTraceId, -1, getTrace().getName()));
+            builder.add(new TmfTreeDataModel(fTraceId, -1, Collections.singletonList(getTrace().getName())));
 
             for (int quark : quarks) {
                 String seriesName = ss.getAttributeName(quark);
@@ -376,17 +382,17 @@
                     String uniqueName = fQuarkToString.computeIfAbsent(quark, q -> getUniqueNameFor(tempSeriesName));
                     // Check if an ID has already been created for this quark.
                     Long id = fIdToQuark.inverse().computeIfAbsent(quark, q -> ENTRY_IDS.getAndIncrement());
-                    builder.add(new TmfTreeDataModel(id, fTraceId, uniqueName));
+                    builder.add(new TmfTreeDataModel(id, fTraceId, Collections.singletonList(uniqueName)));
                 }
             }
 
             ImmutableList<ITmfTreeDataModel> list = builder.build();
             if (isComplete) {
-                TmfModelResponse<List<ITmfTreeDataModel>> tmfModelResponse = new TmfModelResponse<>(list, ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
+                TmfModelResponse<TmfTreeModel<ITmfTreeDataModel>> tmfModelResponse = new TmfModelResponse<>(new TmfTreeModel<>(Collections.emptyList(), list), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
                 fCached = tmfModelResponse;
                 return tmfModelResponse;
             }
-            return new TmfModelResponse<>(list, ITmfResponse.Status.RUNNING, CommonStatusMessage.RUNNING);
+            return new TmfModelResponse<>(new TmfTreeModel<>(Collections.emptyList(), list), ITmfResponse.Status.RUNNING, CommonStatusMessage.RUNNING);
         } catch (StateSystemDisposedException e) {
             return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, CommonStatusMessage.STATE_SYSTEM_FAILED);
         } finally {
@@ -413,4 +419,24 @@
     public String getId() {
         return ID;
     }
+
+    @Deprecated
+    @Override
+    public TmfModelResponse<ITmfXyModel> fetchXY(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        Map<String, Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        return fetchXY(parameters, monitor);
+    }
+
+    @Deprecated
+    @Override
+    public TmfModelResponse<List<ITmfTreeDataModel>> fetchTree(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        Map<String, Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        TmfModelResponse<@NonNull TmfTreeModel<@NonNull ITmfTreeDataModel>> response = fetchTree(parameters, monitor);
+        TmfTreeModel<@NonNull ITmfTreeDataModel> model = response.getModel();
+        List<ITmfTreeDataModel> treeModel = null;
+        if (model != null) {
+            treeModel = model.getEntries();
+        }
+        return new TmfModelResponse<>(treeModel, response.getStatus(), response.getStatusMessage());
+    }
 }
diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/output/DataDrivenTimeGraphDataProvider.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/output/DataDrivenTimeGraphDataProvider.java
index 480f356..64a5451 100644
--- a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/output/DataDrivenTimeGraphDataProvider.java
+++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/output/DataDrivenTimeGraphDataProvider.java
@@ -29,11 +29,12 @@
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.output.DataDrivenOutputEntry.IdGetter;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.output.DataDrivenOutputEntry.QuarkCallback;
 import org.eclipse.tracecompass.internal.tmf.core.model.AbstractTmfTraceDataProvider;
-import org.eclipse.tracecompass.internal.tmf.core.model.filters.TimeGraphStateQueryFilter;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
 import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
 import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
 import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
 import org.eclipse.tracecompass.tmf.core.model.CommonStatusMessage;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
@@ -42,8 +43,10 @@
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphRowModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphState;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphEntryModel;
+import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphRowModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphState;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.response.ITmfResponse.Status;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
@@ -106,7 +109,7 @@
     }
 
     @Override
-    public TmfModelResponse<@NonNull List<TimeGraphEntryModel>> fetchTree(@NonNull TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public final TmfModelResponse<TmfTreeModel<@NonNull TimeGraphEntryModel>> fetchTree(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         List<TimeGraphEntryModel> entryList = new ArrayList<>();
         boolean isComplete = true;
 
@@ -128,7 +131,8 @@
         }
         Status status = isComplete ? Status.COMPLETED : Status.RUNNING;
         String msg = isComplete ? CommonStatusMessage.COMPLETED : CommonStatusMessage.RUNNING;
-        return new TmfModelResponse<>(entryList, status, msg);
+        TmfTreeModel<@NonNull TimeGraphEntryModel> tree = new TmfTreeModel<>(Collections.emptyList(), entryList);
+        return new TmfModelResponse<>(tree, status, msg);
     }
 
     @Override
@@ -137,7 +141,15 @@
     }
 
     @Override
-    public @NonNull TmfModelResponse<@NonNull List<@NonNull ITimeGraphRowModel>> fetchRowModel(@NonNull SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public @NonNull TmfModelResponse<@NonNull TimeGraphModel> fetchRowModel(@NonNull Map<@NonNull String, @NonNull Object> fetchParameters, @Nullable IProgressMonitor monitor) {
+        // TODO server: Parameters validation should be handle separately. It
+        // can be either in the data provider itself or before calling it. It
+        // will avoid the creation of filters and the content of the map can be
+        // use directly.
+        SelectionTimeQueryFilter filter = FetchParametersUtils.createSelectionTimeQuery(fetchParameters);
+        if (filter == null) {
+            return new TmfModelResponse<>(null, Status.FAILED, CommonStatusMessage.INCORRECT_QUERY_PARAMETERS);
+        }
         Table<ITmfStateSystem, Integer, Long> table = HashBasedTable.create();
         for (Long id : filter.getSelectedItems()) {
             Pair<ITmfStateSystem, Integer> pair = fIDToDisplayQuark.get(id);
@@ -148,21 +160,21 @@
         List<@NonNull ITimeGraphRowModel> allRows = new ArrayList<>();
         try {
             for (Entry<ITmfStateSystem, Map<Integer, Long>> ssEntry : table.rowMap().entrySet()) {
-                Collection<@NonNull ITimeGraphRowModel> rows = createRows(ssEntry.getKey(), ssEntry.getValue(), filter.getTimesRequested(), filter, monitor);
+                Collection<@NonNull ITimeGraphRowModel> rows = createRows(ssEntry.getKey(), ssEntry.getValue(), fetchParameters, monitor);
                 allRows.addAll(rows);
             }
         } catch (IndexOutOfBoundsException | TimeRangeException | StateSystemDisposedException e) {
             return new TmfModelResponse<>(null, Status.FAILED, CommonStatusMessage.STATE_SYSTEM_FAILED);
         }
-        return new TmfModelResponse<>(allRows, Status.COMPLETED, CommonStatusMessage.COMPLETED);
+        return new TmfModelResponse<>(new TimeGraphModel(allRows), Status.COMPLETED, CommonStatusMessage.COMPLETED);
     }
 
     private Collection<ITimeGraphRowModel> createRows(ITmfStateSystem ss, Map<Integer, Long> idToDisplayQuark,
-            long[] timesRequested, SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) throws StateSystemDisposedException {
+            Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) throws StateSystemDisposedException {
         Map<@NonNull Integer, @NonNull Predicate<@NonNull Multimap<@NonNull String, @NonNull String>>> predicates = new HashMap<>();
-        if (filter instanceof TimeGraphStateQueryFilter) {
-            TimeGraphStateQueryFilter timeEventFilter = (TimeGraphStateQueryFilter) filter;
-            predicates.putAll(computeRegexPredicate(timeEventFilter));
+        Multimap<@NonNull Integer, @NonNull String> regexesMap = DataProviderParameterUtils.extractRegexFilter(fetchParameters);
+        if (regexesMap != null) {
+            predicates.putAll(computeRegexPredicate(regexesMap));
         }
 
         long currentEndTime = ss.getCurrentEndTime();
@@ -170,6 +182,7 @@
         for (Entry<Integer, Long> entry : idToDisplayQuark.entrySet()) {
             quarkToRow.put(entry.getKey(), new TimeGraphRowModel(entry.getValue(), new ArrayList<>()));
         }
+        List<Long> timesRequested = DataProviderParameterUtils.extractTimeRequested(fetchParameters);
         for (ITmfStateInterval interval : ss.query2D(idToDisplayQuark.keySet(), getTimes(ss, timesRequested))) {
             if (monitor != null && monitor.isCanceled()) {
                 return Collections.emptyList();
@@ -204,7 +217,7 @@
         return new TimeGraphState(time, duration, Integer.MIN_VALUE);
     }
 
-    private static Set<Long> getTimes(ITmfStateSystem key, long[] timesRequested) {
+    private static Set<Long> getTimes(ITmfStateSystem key, List<Long> timesRequested) {
         Set<@NonNull Long> times = new HashSet<>();
         for (long t : timesRequested) {
             if (key.getStartTime() <= t && t <= key.getCurrentEndTime()) {
@@ -215,15 +228,55 @@
     }
 
     @Override
-    public @NonNull TmfModelResponse<@NonNull List<@NonNull ITimeGraphArrow>> fetchArrows(@NonNull TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public @NonNull TmfModelResponse<List<ITimeGraphArrow>> fetchArrows(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         return new TmfModelResponse<>(null, Status.COMPLETED, CommonStatusMessage.COMPLETED);
     }
 
     @Override
-    public @NonNull TmfModelResponse<@NonNull Map<@NonNull String, @NonNull String>> fetchTooltip(@NonNull SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public @NonNull TmfModelResponse<Map<String, String>> fetchTooltip(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         return new TmfModelResponse<>(null, Status.COMPLETED, CommonStatusMessage.COMPLETED);
     }
 
+    @Deprecated
+    @Override
+    public TmfModelResponse<List<TimeGraphEntryModel>> fetchTree(@NonNull TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        @NonNull Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        TmfModelResponse<TmfTreeModel<@NonNull TimeGraphEntryModel>> response = fetchTree(parameters, monitor);
+        TmfTreeModel<@NonNull TimeGraphEntryModel> model = response.getModel();
+        List<TimeGraphEntryModel> treeModel = null;
+        if (model != null) {
+            treeModel = model.getEntries();
+        }
+        return new TmfModelResponse<>(treeModel, response.getStatus(), response.getStatusMessage());
+    }
+
+    @Deprecated
+    @Override
+    public @NonNull TmfModelResponse<@NonNull List<@NonNull ITimeGraphRowModel>> fetchRowModel(@NonNull SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        @NonNull Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.selectionTimeQueryToMap(filter);
+        TmfModelResponse<@NonNull TimeGraphModel> response = fetchRowModel(parameters, monitor);
+        TimeGraphModel model = response.getModel();
+        List<@NonNull ITimeGraphRowModel> rows = null;
+        if (model != null) {
+            rows = model.getRows();
+        }
+        return new TmfModelResponse<>(rows, response.getStatus(), response.getStatusMessage());
+    }
+
+    @Deprecated
+    @Override
+    public @NonNull TmfModelResponse<@NonNull List<@NonNull ITimeGraphArrow>> fetchArrows(@NonNull TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        Map<String, Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        return fetchArrows(parameters, monitor);
+    }
+
+    @Deprecated
+    @Override
+    public @NonNull TmfModelResponse<@NonNull Map<@NonNull String, @NonNull String>> fetchTooltip(@NonNull SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        Map<String, Object> parameters = FetchParametersUtils.selectionTimeQueryToMap(filter);
+        return fetchTooltip(parameters, monitor);
+    }
+
     /**
      * Get the values
      *
diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/output/DataDrivenXYDataProvider.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/output/DataDrivenXYDataProvider.java
index 00bf56e..31e675a 100644
--- a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/output/DataDrivenXYDataProvider.java
+++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/output/DataDrivenXYDataProvider.java
@@ -28,6 +28,7 @@
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.output.DataDrivenOutputEntry.QuarkCallback;
 import org.eclipse.tracecompass.internal.tmf.core.model.AbstractTmfTraceDataProvider;
 import org.eclipse.tracecompass.internal.tmf.core.model.TmfXyResponseFactory;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
 import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
 import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
@@ -37,6 +38,7 @@
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphEntryModel;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.model.xy.ITmfTreeXYDataProvider;
 import org.eclipse.tracecompass.tmf.core.model.xy.ITmfXyModel;
 import org.eclipse.tracecompass.tmf.core.model.xy.IYModel;
@@ -75,7 +77,7 @@
     public enum DisplayType {
         /** Displays absolute value */
         ABSOLUTE,
-        /** Disaplys the difference between current and previous value */
+        /** Displays the difference between current and previous value */
         DELTA
     }
 
@@ -92,7 +94,7 @@
     private final List<DataDrivenOutputEntry> fEntries;
     private final String fId;
 
-    private @Nullable TmfModelResponse<List<ITmfTreeDataModel>> fCached;
+    private @Nullable TmfModelResponse<TmfTreeModel<ITmfTreeDataModel>> fCached;
 
     private final ReentrantReadWriteLock fLock = new ReentrantReadWriteLock(false);
 
@@ -128,9 +130,21 @@
     }
 
     @Override
+    @Deprecated
     public TmfModelResponse<ITmfXyModel> fetchXY(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        return fetchXY(FetchParametersUtils.timeQueryToMap(filter), monitor);
+    }
+
+    @Override
+    public TmfModelResponse<ITmfXyModel> fetchXY(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
+        TimeQueryFilter filter = FetchParametersUtils.createTimeQuery(fetchParameters);
+        if (filter == null) {
+            return TmfXyResponseFactory.createFailedResponse(CommonStatusMessage.INCORRECT_QUERY_PARAMETERS);
+        }
         long[] xValues = filter.getTimesRequested();
-        if (!(filter instanceof SelectionTimeQueryFilter)) {
+
+        filter = FetchParametersUtils.createSelectionTimeQuery(fetchParameters);
+        if (filter == null) {
             return TmfXyResponseFactory.create(TITLE, xValues, Collections.emptyMap(), true);
         }
 
@@ -179,7 +193,7 @@
         }
 
         boolean complete = ss.waitUntilBuilt(0) || filter.getEnd() <= currentEnd;
-        return TmfXyResponseFactory.create(TITLE, xValues, Maps.uniqueIndex(map.values(), IYModel::getName), complete);
+        return TmfXyResponseFactory.create(TITLE, xValues, Maps.uniqueIndex(map.values(), value -> Long.toString(value.getId())), complete);
     }
 
     private static void getSeriesDelta(double[] data) {
@@ -223,7 +237,20 @@
     }
 
     @Override
+    @Deprecated
     public TmfModelResponse<List<ITmfTreeDataModel>> fetchTree(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        Map<String, Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        TmfModelResponse<TmfTreeModel<ITmfTreeDataModel>> response = fetchTree(parameters, monitor);
+        TmfTreeModel<ITmfTreeDataModel> model = response.getModel();
+        List<ITmfTreeDataModel> treeModel = null;
+        if (model != null) {
+            treeModel = model.getEntries();
+        }
+        return new TmfModelResponse<>(treeModel, response.getStatus(), response.getStatusMessage());
+    }
+
+    @Override
+    public TmfModelResponse<TmfTreeModel<ITmfTreeDataModel>> fetchTree(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         fLock.readLock().lock();
         try {
             if (fCached != null) {
@@ -256,15 +283,14 @@
             fIdToTitle.clear();
             entryList.forEach(e -> fIdToTitle.put(e.getId(), e.getName()));
             if (isComplete) {
-                TmfModelResponse<List<ITmfTreeDataModel>> tmfModelResponse = new TmfModelResponse<>(entryList, ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
+                TmfModelResponse<TmfTreeModel<ITmfTreeDataModel>> tmfModelResponse = new TmfModelResponse<>(new TmfTreeModel<>(Collections.emptyList(), entryList), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
                 fCached = tmfModelResponse;
                 return tmfModelResponse;
             }
-            return new TmfModelResponse<>(entryList, ITmfResponse.Status.RUNNING, CommonStatusMessage.RUNNING);
+            return new TmfModelResponse<>(new TmfTreeModel<>(Collections.emptyList(), entryList), ITmfResponse.Status.RUNNING, CommonStatusMessage.RUNNING);
         } finally {
             fLock.writeLock().unlock();
         }
-
     }
 
     @Override
diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/timegraph/XmlTimeGraphView.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/timegraph/XmlTimeGraphView.java
index 3dcb557..d9faa93 100644
--- a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/timegraph/XmlTimeGraphView.java
+++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/ui/views/timegraph/XmlTimeGraphView.java
@@ -16,7 +16,6 @@
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 
 import org.eclipse.core.runtime.IProgressMonitor;
@@ -30,12 +29,14 @@
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.output.XmlDataProviderManager;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.Activator;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views.XmlViewInfo;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.tmf.analysis.xml.core.module.TmfXmlStrings;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphDataProvider;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphEntryModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphState;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphEntryModel;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
@@ -252,7 +253,7 @@
             return;
         }
         while (!complete && !subMonitor.isCanceled()) {
-            TmfModelResponse<List<TimeGraphEntryModel>> response = provider.fetchTree(new TimeQueryFilter(0, Long.MAX_VALUE, 2), subMonitor);
+            TmfModelResponse<TmfTreeModel<@NonNull TimeGraphEntryModel>> response = provider.fetchTree(FetchParametersUtils.timeQueryToMap(new TimeQueryFilter(0, Long.MAX_VALUE, 2)), subMonitor);
             if (response.getStatus() == ITmfResponse.Status.FAILED) {
                 Activator.logError("XML Time Graph Data Provider failed: " + response.getStatusMessage()); //$NON-NLS-1$
                 return;
@@ -261,13 +262,13 @@
             }
             complete = response.getStatus() == ITmfResponse.Status.COMPLETED;
 
-            List<TimeGraphEntryModel> model = response.getModel();
+            TmfTreeModel<@NonNull TimeGraphEntryModel> model = response.getModel();
             if (model != null) {
                 synchronized (fEntries) {
                     /*
                      * Ensure that all the entries exist and are up to date.
                      */
-                    for (TimeGraphEntryModel entry : model) {
+                    for (TimeGraphEntryModel entry : model.getEntries()) {
                         TimeGraphEntry tgEntry = fEntries.get(provider, entry.getId());
                         if (tgEntry == null) {
                             if (entry.getParentId() == -1) {
diff --git a/tmf/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/dataprovider/DataProviderParameterTest.java b/tmf/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/dataprovider/DataProviderParameterTest.java
new file mode 100644
index 0000000..d260328
--- /dev/null
+++ b/tmf/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/dataprovider/DataProviderParameterTest.java
@@ -0,0 +1,138 @@
+/**********************************************************************
+ * Copyright (c) 2019 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ **********************************************************************/
+
+package org.eclipse.tracecompass.tmf.core.tests.dataprovider;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test {@link DataProviderParameterUtils}
+ *
+ * @author Simon Delisle
+ */
+@NonNullByDefault
+public class DataProviderParameterTest {
+
+    private static final String CUSTOM_KEY = "MyKey";
+    private static Map<String, Object> fParameters = new HashMap<>();
+    private List<?> fLongList = Arrays.asList(new Long(1), new Long(2), new Long(3));
+    private List<?> fIntList = Arrays.asList(new Integer(1), new Integer(2), new Integer(3));
+    private List<?> fMixedList = Arrays.asList(new Integer(1), new Long(2), new Integer(3));
+    private String fWrongParameter = "Unsupported";
+
+    /**
+     * Setup everything necessary for all tests
+     */
+    @BeforeClass
+    public static void setUp() {
+        fParameters.put(DataProviderParameterUtils.REQUESTED_TIME_KEY, Collections.emptyList());
+        fParameters.put(DataProviderParameterUtils.REQUESTED_ITEMS_KEY, Collections.emptyList());
+    }
+
+    /**
+     * Test {@link DataProviderParameterUtils#extractTimeRequested(Map)} by
+     * passing 4 different values
+     */
+    @Test
+    public void testExtractTimeRequested() {
+        fParameters.put(DataProviderParameterUtils.REQUESTED_TIME_KEY, fLongList);
+        List<@NonNull Long> timeRequested = DataProviderParameterUtils.extractTimeRequested(fParameters);
+        assertNotNull(timeRequested);
+        testLongList(timeRequested);
+
+        fParameters.put(DataProviderParameterUtils.REQUESTED_TIME_KEY, fIntList);
+        timeRequested = DataProviderParameterUtils.extractTimeRequested(fParameters);
+        assertNotNull(timeRequested);
+        testLongList(timeRequested);
+
+        fParameters.put(DataProviderParameterUtils.REQUESTED_TIME_KEY, fMixedList);
+        timeRequested = DataProviderParameterUtils.extractTimeRequested(fParameters);
+        assertNotNull(timeRequested);
+        testLongList(timeRequested);
+
+        fParameters.put(DataProviderParameterUtils.REQUESTED_TIME_KEY, fWrongParameter);
+        timeRequested = DataProviderParameterUtils.extractTimeRequested(fParameters);
+        assertNull(timeRequested);
+    }
+
+    /**
+     * Test {@link DataProviderParameterUtils#extractSelectedItems(Map)} by
+     * passing 4 different values
+     */
+    @Test
+    public void testExtractSelectedItems() {
+        fParameters.put(DataProviderParameterUtils.REQUESTED_ITEMS_KEY, fLongList);
+        List<@NonNull Long> items = DataProviderParameterUtils.extractSelectedItems(fParameters);
+        assertNotNull(items);
+        testLongList(items);
+
+        fParameters.put(DataProviderParameterUtils.REQUESTED_ITEMS_KEY, fIntList);
+        items = DataProviderParameterUtils.extractSelectedItems(fParameters);
+        assertNotNull(items);
+        testLongList(items);
+
+        fParameters.put(DataProviderParameterUtils.REQUESTED_ITEMS_KEY, fMixedList);
+        items = DataProviderParameterUtils.extractSelectedItems(fParameters);
+        assertNotNull(items);
+        testLongList(items);
+
+        fParameters.put(DataProviderParameterUtils.REQUESTED_ITEMS_KEY, fWrongParameter);
+        items = DataProviderParameterUtils.extractSelectedItems(fParameters);
+        assertNull(items);
+    }
+
+    /**
+     * Test {@link DataProviderParameterUtils#extractLongList(Map, String)}
+     */
+    @Test
+    public void testExtractLongList() {
+        fParameters.put(CUSTOM_KEY, fLongList);
+        List<Long> longList = DataProviderParameterUtils.extractLongList(fParameters, CUSTOM_KEY);
+        assertNotNull(longList);
+        testLongList(longList);
+    }
+
+    /**
+     * Test {@link DataProviderParameterUtils#extractBoolean(Map, String)}
+     */
+    @Test
+    public void testExtractBoolean() {
+        fParameters.put(CUSTOM_KEY, new Boolean(true));
+        Boolean extractedBoolean = DataProviderParameterUtils.extractBoolean(fParameters, CUSTOM_KEY);
+        assertNotNull(extractedBoolean);
+        assertTrue(extractedBoolean);
+
+        fParameters.put(CUSTOM_KEY, new Boolean(false));
+        extractedBoolean = DataProviderParameterUtils.extractBoolean(fParameters, CUSTOM_KEY);
+        assertNotNull(extractedBoolean);
+        assertFalse(extractedBoolean);
+    }
+
+    private static void testLongList(List<?> listToTest) {
+        assertEquals(3, listToTest.size());
+        assertTrue(listToTest.stream().allMatch(e -> e instanceof Long));
+    }
+
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/dataprovider/FetchParametersTest.java b/tmf/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/dataprovider/FetchParametersTest.java
new file mode 100644
index 0000000..b5c5660
--- /dev/null
+++ b/tmf/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/dataprovider/FetchParametersTest.java
@@ -0,0 +1,115 @@
+/**********************************************************************
+ * Copyright (c) 2019 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ **********************************************************************/
+
+package org.eclipse.tracecompass.tmf.core.tests.dataprovider;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.tracecompass.internal.provisional.tmf.core.model.filters.VirtualTableQueryFilter;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
+import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
+import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
+import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test {@link FetchParametersUtils}
+ *
+ * @author Simon Delisle
+ */
+@NonNullByDefault
+public class FetchParametersTest {
+
+    private static List<Long> fTimeList = Arrays.asList(1L, 2L, 3L);
+    private static List<Long> fItemList = Arrays.asList(0L, 1L, 2L);
+    private static final int TABLE_COUNT = 5;
+    private static final long TABLE_INDEX = 0;
+
+    private static Map<String, Object> fExpectedTimeQueryMap = new HashMap<>();
+    private static Map<String, Object> fExpectedSelectionTimeQueryMap = new HashMap<>();
+    private static Map<String, Object> fExpectedVirtualTableQueryMap = new HashMap<>();
+
+    private TimeQueryFilter fExpectedTimeQuery = new TimeQueryFilter(fTimeList);
+    private SelectionTimeQueryFilter fExpectedSelectionTimeQuery = new SelectionTimeQueryFilter(fTimeList, fItemList);
+    private VirtualTableQueryFilter fExpectedVirtualTableQuery = new VirtualTableQueryFilter(fItemList, TABLE_INDEX, TABLE_COUNT);
+
+    /**
+     * Setup everything necessary for all tests
+     */
+    @BeforeClass
+    public static void setUp() {
+        fExpectedTimeQueryMap.put(DataProviderParameterUtils.REQUESTED_TIME_KEY, fTimeList);
+
+        fExpectedSelectionTimeQueryMap.put(DataProviderParameterUtils.REQUESTED_TIME_KEY, fTimeList);
+        fExpectedSelectionTimeQueryMap.put(DataProviderParameterUtils.REQUESTED_ITEMS_KEY, fItemList);
+
+        fExpectedVirtualTableQueryMap.put(DataProviderParameterUtils.REQUESTED_COLUMN_IDS_KEY, fItemList);
+        fExpectedVirtualTableQueryMap.put(DataProviderParameterUtils.REQUESTED_TABLE_INDEX_KEY, TABLE_INDEX);
+        fExpectedVirtualTableQueryMap.put(DataProviderParameterUtils.REQUESTED_TABLE_COUNT_KEY, TABLE_COUNT);
+    }
+
+    /**
+     * Test {@link FetchParametersUtils#timeQueryToMap(TimeQueryFilter)} and
+     * {@link FetchParametersUtils#createTimeQuery(Map)}
+     */
+    @Test
+    public void testTimeQuery() {
+        TimeQueryFilter timeQuery = FetchParametersUtils.createTimeQuery(fExpectedTimeQueryMap);
+        assertNotNull(timeQuery);
+        assertEquals(fExpectedTimeQuery, timeQuery);
+
+        Map<String, Object> timeQueryMap = FetchParametersUtils.timeQueryToMap(fExpectedTimeQuery);
+        assertFalse(timeQueryMap.isEmpty());
+        assertEquals(fExpectedTimeQueryMap, timeQueryMap);
+    }
+
+    /**
+     * Test
+     * {@link FetchParametersUtils#selectionTimeQueryToMap(SelectionTimeQueryFilter)}
+     * and {@link FetchParametersUtils#createSelectionTimeQuery(Map)}
+     */
+    @Test
+    public void testSelectionTimeQuery() {
+        TimeQueryFilter selectionTimeQuery = FetchParametersUtils.createSelectionTimeQuery(fExpectedSelectionTimeQueryMap);
+        assertNotNull(selectionTimeQuery);
+        assertEquals(fExpectedSelectionTimeQuery, selectionTimeQuery);
+
+        Map<String, Object> selectionTimeQueryMap = FetchParametersUtils.selectionTimeQueryToMap(fExpectedSelectionTimeQuery);
+        assertFalse(selectionTimeQueryMap.isEmpty());
+        assertEquals(fExpectedSelectionTimeQueryMap, selectionTimeQueryMap);
+    }
+
+    /**
+     * Test
+     * {@link FetchParametersUtils#virtualTableQueryToMap(VirtualTableQueryFilter)}
+     * and {@link FetchParametersUtils#createVirtualTableQueryFilter(Map)}
+     */
+    @Test
+    public void testVirtualTableQuery() {
+        VirtualTableQueryFilter virtualTableQuery = FetchParametersUtils.createVirtualTableQueryFilter(fExpectedVirtualTableQueryMap);
+        assertNotNull(virtualTableQuery);
+        assertEquals(fExpectedVirtualTableQuery, virtualTableQuery);
+
+        Map<String, Object> virtualTableQueryMap = FetchParametersUtils.virtualTableQueryToMap(fExpectedVirtualTableQuery);
+        assertFalse(virtualTableQueryMap.isEmpty());
+        assertEquals(fExpectedVirtualTableQueryMap.get(DataProviderParameterUtils.REQUESTED_COLUMN_IDS_KEY), virtualTableQueryMap.get(DataProviderParameterUtils.REQUESTED_COLUMN_IDS_KEY));
+        assertEquals(fExpectedVirtualTableQueryMap.get(DataProviderParameterUtils.REQUESTED_TABLE_INDEX_KEY), virtualTableQueryMap.get(DataProviderParameterUtils.REQUESTED_TABLE_INDEX_KEY));
+        assertEquals(fExpectedVirtualTableQueryMap.get(DataProviderParameterUtils.REQUESTED_TABLE_COUNT_KEY), virtualTableQueryMap.get(DataProviderParameterUtils.REQUESTED_TABLE_COUNT_KEY));
+    }
+
+}
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 e52332e..ec1eb7e 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
@@ -32,8 +32,11 @@
 import org.eclipse.tracecompass.internal.provisional.tmf.core.model.table.ITmfVirtualTableDataProvider;
 import org.eclipse.tracecompass.internal.provisional.tmf.core.model.table.ITmfVirtualTableModel;
 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.exceptions.TmfTraceException;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestTrace;
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
@@ -79,18 +82,19 @@
     }
 
     private static Map<String, Long> fetchColumnId() {
-        List<TmfEventTableColumnDataModel> columns = fProvider.fetchTree(new TimeQueryFilter(0, 0, 1), null).getModel();
+        TmfTreeModel<TmfEventTableColumnDataModel> columns = fProvider.fetchTree(FetchParametersUtils.timeQueryToMap(new TimeQueryFilter(0, 0, 1)), null).getModel();
         if (columns == null) {
             return Collections.emptyMap();
         }
 
+        List<TmfEventTableColumnDataModel> columnEntries = columns.getEntries();
         // Order should be timestamp, event type and contents
-        assertEquals(TIMESTAMP_COLUMN_NAME, columns.get(0).getName());
-        assertEquals(EVENT_TYPE_COLUMN_NAME, columns.get(1).getName());
-        assertEquals(CONTENTS_COLUMN_NAME, columns.get(2).getName());
+        assertEquals(TIMESTAMP_COLUMN_NAME, columnEntries.get(0).getName());
+        assertEquals(EVENT_TYPE_COLUMN_NAME, columnEntries.get(1).getName());
+        assertEquals(CONTENTS_COLUMN_NAME, columnEntries.get(2).getName());
 
         Map<String, Long> expectedColumns = new LinkedHashMap<>();
-        for (TmfEventTableColumnDataModel column : columns) {
+        for (TmfEventTableColumnDataModel column : columnEntries) {
             expectedColumns.put(column.getName(), column.getId());
         }
         return expectedColumns;
@@ -119,14 +123,16 @@
         assertNotNull(timestampColumnId);
         assertNotNull(eventTypeColumnId);
         assertNotNull(contentsColumnId);
-        List<TmfEventTableColumnDataModel> expectedColumnModel = Arrays.asList(
-                new TmfEventTableColumnDataModel(timestampColumnId, -1, TIMESTAMP_COLUMN_NAME, "", false),
-                new TmfEventTableColumnDataModel(eventTypeColumnId, -1, EVENT_TYPE_COLUMN_NAME, "The type of this event. This normally determines the field layout.", false),
-                new TmfEventTableColumnDataModel(contentsColumnId, -1, CONTENTS_COLUMN_NAME, "The fields (or payload) of this event", false));
+        List<TmfEventTableColumnDataModel> expectedColumnEntries = Arrays.asList(
+                new TmfEventTableColumnDataModel(timestampColumnId, -1, Collections.singletonList(TIMESTAMP_COLUMN_NAME), "", false),
+                new TmfEventTableColumnDataModel(eventTypeColumnId, -1, Collections.singletonList(EVENT_TYPE_COLUMN_NAME), "The type of this event. This normally determines the field layout.", false),
+                new TmfEventTableColumnDataModel(contentsColumnId, -1, Collections.singletonList(CONTENTS_COLUMN_NAME), "The fields (or payload) of this event", false));
 
-        TmfModelResponse<List<TmfEventTableColumnDataModel>> response = fProvider.fetchTree(new TimeQueryFilter(0, 0, 1), null);
-        List<TmfEventTableColumnDataModel> currentColumnModel = response.getModel();
-        assertEquals(expectedColumnModel, currentColumnModel);
+        TmfModelResponse<TmfTreeModel<TmfEventTableColumnDataModel>> response = fProvider.fetchTree(FetchParametersUtils.timeQueryToMap(new TimeQueryFilter(0, 0, 1)), null);
+        TmfTreeModel<TmfEventTableColumnDataModel> currentColumnModel = response.getModel();
+        assertNotNull(currentColumnModel);
+        List<TmfEventTableColumnDataModel> currentColumnEntries = currentColumnModel.getEntries();
+        assertEquals(expectedColumnEntries, currentColumnEntries);
     }
 
     /**
@@ -138,13 +144,13 @@
         VirtualTableQueryFilter queryFilter = new EventTableQueryFilter(Collections.emptyList(), 0, 5, null);
 
         List<EventTableLine> expectedData = Arrays.asList(
-                new EventTableLine(Arrays.asList(lineTimestamp(1), "Type-0", ""), 0, TmfTimestamp.fromMillis(1), 0, 0),
-                new EventTableLine(Arrays.asList(lineTimestamp(2), "Type-1", ""), 1, TmfTimestamp.fromMillis(2), 1, 0),
-                new EventTableLine(Arrays.asList(lineTimestamp(3), "Type-2", ""), 2, TmfTimestamp.fromMillis(3), 2, 0),
-                new EventTableLine(Arrays.asList(lineTimestamp(4), "Type-3", ""), 3, TmfTimestamp.fromMillis(4), 3, 0),
-                new EventTableLine(Arrays.asList(lineTimestamp(5), "Type-4", ""), 4, TmfTimestamp.fromMillis(5), 4, 0));
+                new EventTableLine(Arrays.asList(new VirtualTableCell(lineTimestamp(1)), new VirtualTableCell("Type-0"), new VirtualTableCell("")), 0, TmfTimestamp.fromMillis(1), 0, 0),
+                new EventTableLine(Arrays.asList(new VirtualTableCell(lineTimestamp(2)), new VirtualTableCell("Type-1"), new VirtualTableCell("")), 1, TmfTimestamp.fromMillis(2), 1, 0),
+                new EventTableLine(Arrays.asList(new VirtualTableCell(lineTimestamp(3)), new VirtualTableCell("Type-2"), new VirtualTableCell("")), 2, TmfTimestamp.fromMillis(3), 2, 0),
+                new EventTableLine(Arrays.asList(new VirtualTableCell(lineTimestamp(4)), new VirtualTableCell("Type-3"), new VirtualTableCell("")), 3, TmfTimestamp.fromMillis(4), 3, 0),
+                new EventTableLine(Arrays.asList(new VirtualTableCell(lineTimestamp(5)), new VirtualTableCell("Type-4"), new VirtualTableCell("")), 4, TmfTimestamp.fromMillis(5), 4, 0));
 
-        TmfModelResponse<ITmfVirtualTableModel<EventTableLine>> response = fProvider.fetchLines(queryFilter, null);
+        TmfModelResponse<ITmfVirtualTableModel<EventTableLine>> response = fProvider.fetchLines(FetchParametersUtils.virtualTableQueryToMap(queryFilter), null);
         ITmfVirtualTableModel<EventTableLine> currentModel = response.getModel();
 
         ITmfVirtualTableModel<EventTableLine> expectedModel = new TmfVirtualTableModel<>(new ArrayList<>(fColumns.values()), expectedData, 0, fTrace.getNbEvents());
@@ -158,12 +164,12 @@
     @Test
     public void testDataProviderWithOutOfBoundIndex() {
         VirtualTableQueryFilter queryFilter = new EventTableQueryFilter(Collections.emptyList(), 2000000, 5, null);
-        TmfModelResponse<ITmfVirtualTableModel<EventTableLine>> response = fProvider.fetchLines(queryFilter, null);
+        TmfModelResponse<ITmfVirtualTableModel<EventTableLine>> response = fProvider.fetchLines(FetchParametersUtils.virtualTableQueryToMap(queryFilter), null);
         ITmfVirtualTableModel<EventTableLine> currentModel = response.getModel();
 
         assertNotNull(currentModel);
         assertEquals(new ArrayList<>(fColumns.values()), currentModel.getColumnIds());
-        assertTrue(currentModel.getData().isEmpty());
+        assertTrue(currentModel.getLines().isEmpty());
     }
 
     /**
@@ -178,13 +184,13 @@
 
         List<Long> expectedColumnsId = Arrays.asList(eventTypeColumnId);
         List<EventTableLine> expectedData = Arrays.asList(
-                new EventTableLine(Arrays.asList("Type-5"), 5, TmfTimestamp.fromMillis(6), 5, 0),
-                new EventTableLine(Arrays.asList("Type-6"), 6, TmfTimestamp.fromMillis(7), 6, 0),
-                new EventTableLine(Arrays.asList("Type-0"), 7, TmfTimestamp.fromMillis(8), 7, 0),
-                new EventTableLine(Arrays.asList("Type-1"), 8, TmfTimestamp.fromMillis(9), 8, 0),
-                new EventTableLine(Arrays.asList("Type-2"), 9, TmfTimestamp.fromMillis(10), 9, 0));
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-5")), 5, TmfTimestamp.fromMillis(6), 5, 0),
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-6")), 6, TmfTimestamp.fromMillis(7), 6, 0),
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-0")), 7, TmfTimestamp.fromMillis(8), 7, 0),
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-1")), 8, TmfTimestamp.fromMillis(9), 8, 0),
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-2")), 9, TmfTimestamp.fromMillis(10), 9, 0));
 
-        TmfModelResponse<ITmfVirtualTableModel<EventTableLine>> response = fProvider.fetchLines(queryFilter, null);
+        TmfModelResponse<ITmfVirtualTableModel<EventTableLine>> response = fProvider.fetchLines(FetchParametersUtils.virtualTableQueryToMap(queryFilter), null);
         ITmfVirtualTableModel<EventTableLine> currentModel = response.getModel();
 
         ITmfVirtualTableModel<EventTableLine> expectedModel = new TmfVirtualTableModel<>(expectedColumnsId, expectedData, 5, fTrace.getNbEvents());
@@ -205,13 +211,13 @@
 
         List<Long> expectedColumnsId = Arrays.asList(eventTypeColumnId, timestampColumnId);
         List<EventTableLine> expectedData = Arrays.asList(
-                new EventTableLine(Arrays.asList("Type-3", lineTimestamp(151)), 150, TmfTimestamp.fromMillis(151), 150, 0),
-                new EventTableLine(Arrays.asList("Type-4", lineTimestamp(152)), 151, TmfTimestamp.fromMillis(152), 151, 0),
-                new EventTableLine(Arrays.asList("Type-5", lineTimestamp(153)), 152, TmfTimestamp.fromMillis(153), 152, 0),
-                new EventTableLine(Arrays.asList("Type-6", lineTimestamp(154)), 153, TmfTimestamp.fromMillis(154), 153, 0),
-                new EventTableLine(Arrays.asList("Type-0", lineTimestamp(155)), 154, TmfTimestamp.fromMillis(155), 154, 0));
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-3"), new VirtualTableCell(lineTimestamp(151))), 150, TmfTimestamp.fromMillis(151), 150, 0),
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-4"), new VirtualTableCell(lineTimestamp(152))), 151, TmfTimestamp.fromMillis(152), 151, 0),
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-5"), new VirtualTableCell(lineTimestamp(153))), 152, TmfTimestamp.fromMillis(153), 152, 0),
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-6"), new VirtualTableCell(lineTimestamp(154))), 153, TmfTimestamp.fromMillis(154), 153, 0),
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-0"), new VirtualTableCell(lineTimestamp(155))), 154, TmfTimestamp.fromMillis(155), 154, 0));
 
-        TmfModelResponse<ITmfVirtualTableModel<EventTableLine>> response = fProvider.fetchLines(queryFilter, null);
+        TmfModelResponse<ITmfVirtualTableModel<EventTableLine>> response = fProvider.fetchLines(FetchParametersUtils.virtualTableQueryToMap(queryFilter), null);
         ITmfVirtualTableModel<EventTableLine> currentModel = response.getModel();
 
         ITmfVirtualTableModel<EventTableLine> expectedModel = new TmfVirtualTableModel<>(expectedColumnsId, expectedData, 150, fTrace.getNbEvents());
@@ -225,12 +231,12 @@
     @Test
     public void testDataProviderWithNonExistentColumns() {
         VirtualTableQueryFilter queryFilter = new EventTableQueryFilter(Arrays.asList(10L, 11L), 0, 10, null);
-        TmfModelResponse<ITmfVirtualTableModel<EventTableLine>> response = fProvider.fetchLines(queryFilter, null);
+        TmfModelResponse<ITmfVirtualTableModel<EventTableLine>> response = fProvider.fetchLines(FetchParametersUtils.virtualTableQueryToMap(queryFilter), null);
         ITmfVirtualTableModel<EventTableLine> currentModel = response.getModel();
 
         assertNotNull(currentModel);
         assertTrue(currentModel.getColumnIds().isEmpty());
-        assertTrue(currentModel.getData().isEmpty());
+        assertTrue(currentModel.getLines().isEmpty());
     }
 
     /**
@@ -247,19 +253,20 @@
         Map<Long, String> tableFilter = new HashMap<>();
         tableFilter.put(eventTypeColumnId, "1");
         TmfEventTableFilterModel filterModel = new TmfEventTableFilterModel(tableFilter, null, false);
-
         VirtualTableQueryFilter queryFilter = new EventTableQueryFilter(Arrays.asList(eventTypeColumnId, timestampColumnId), 0, 5, filterModel);
+        Map<String, Object> parameters = FetchParametersUtils.virtualTableQueryToMap(queryFilter);
+        parameters.put(TmfEventTableDataProvider.TABLE_FILTERS_KEY, filterModel);
 
         List<Long> expectedColumnsId = Arrays.asList(eventTypeColumnId, timestampColumnId);
         TmfTimestampFormat.getDefaulTimeFormat().format(TmfTimestamp.fromMillis(2).toNanos());
         List<EventTableLine> expectedData = Arrays.asList(
-                new EventTableLine(Arrays.asList("Type-1", lineTimestamp(2)), 0, TmfTimestamp.fromMillis(2), 1, 0),
-                new EventTableLine(Arrays.asList("Type-1", lineTimestamp(9)), 1, TmfTimestamp.fromMillis(9), 8, 0),
-                new EventTableLine(Arrays.asList("Type-1", lineTimestamp(16)), 2, TmfTimestamp.fromMillis(16), 15, 0),
-                new EventTableLine(Arrays.asList("Type-1", lineTimestamp(23)), 3, TmfTimestamp.fromMillis(23), 22, 0),
-                new EventTableLine(Arrays.asList("Type-1", lineTimestamp(30)), 4, TmfTimestamp.fromMillis(30), 29, 0));
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-1"), new VirtualTableCell(lineTimestamp(2))), 0, TmfTimestamp.fromMillis(2), 1, 0),
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-1"), new VirtualTableCell(lineTimestamp(9))), 1, TmfTimestamp.fromMillis(9), 8, 0),
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-1"), new VirtualTableCell(lineTimestamp(16))), 2, TmfTimestamp.fromMillis(16), 15, 0),
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-1"), new VirtualTableCell(lineTimestamp(23))), 3, TmfTimestamp.fromMillis(23), 22, 0),
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-1"), new VirtualTableCell(lineTimestamp(30))), 4, TmfTimestamp.fromMillis(30), 29, 0));
 
-        TmfModelResponse<ITmfVirtualTableModel<EventTableLine>> response = fProvider.fetchLines(queryFilter, null);
+        TmfModelResponse<ITmfVirtualTableModel<EventTableLine>> response = fProvider.fetchLines(parameters, null);
         ITmfVirtualTableModel<EventTableLine> currentModel = response.getModel();
 
         TmfVirtualTableModel<@NonNull EventTableLine> expectedModel = new TmfVirtualTableModel<>(expectedColumnsId, expectedData, 0, 1429);
@@ -281,18 +288,19 @@
         tableFilter.put(eventTypeColumnId, "0");
         tableFilter.put(timestampColumnId, "8");
         TmfEventTableFilterModel filterModel = new TmfEventTableFilterModel(tableFilter, null, false);
-
         VirtualTableQueryFilter queryFilter = new EventTableQueryFilter(Arrays.asList(1L, 0L), 0, 5, filterModel);
+        Map<String, Object> parameters = FetchParametersUtils.virtualTableQueryToMap(queryFilter);
+        parameters.put(TmfEventTableDataProvider.TABLE_FILTERS_KEY, filterModel);
 
         List<Long> expectedColumnsId = Arrays.asList(eventTypeColumnId, timestampColumnId);
         List<EventTableLine> expectedData = Arrays.asList(
-                new EventTableLine(Arrays.asList("Type-0", lineTimestamp(8)), 0, TmfTimestamp.fromMillis(8), 7, 0),
-                new EventTableLine(Arrays.asList("Type-0", lineTimestamp(78)), 1, TmfTimestamp.fromMillis(78), 77, 0),
-                new EventTableLine(Arrays.asList("Type-0", lineTimestamp(85)), 2, TmfTimestamp.fromMillis(85), 84, 0),
-                new EventTableLine(Arrays.asList("Type-0", lineTimestamp(148)), 3, TmfTimestamp.fromMillis(148), 147, 0),
-                new EventTableLine(Arrays.asList("Type-0", lineTimestamp(183)), 4, TmfTimestamp.fromMillis(183), 182, 0));
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-0"), new VirtualTableCell(lineTimestamp(8))), 0, TmfTimestamp.fromMillis(8), 7, 0),
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-0"), new VirtualTableCell(lineTimestamp(78))), 1, TmfTimestamp.fromMillis(78), 77, 0),
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-0"), new VirtualTableCell(lineTimestamp(85))), 2, TmfTimestamp.fromMillis(85), 84, 0),
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-0"), new VirtualTableCell(lineTimestamp(148))), 3, TmfTimestamp.fromMillis(148), 147, 0),
+                new EventTableLine(Arrays.asList(new VirtualTableCell("Type-0"), new VirtualTableCell(lineTimestamp(183))), 4, TmfTimestamp.fromMillis(183), 182, 0));
 
-        TmfModelResponse<ITmfVirtualTableModel<EventTableLine>> response = fProvider.fetchLines(queryFilter, null);
+        TmfModelResponse<ITmfVirtualTableModel<EventTableLine>> response = fProvider.fetchLines(parameters, null);
         ITmfVirtualTableModel<EventTableLine> currentModel = response.getModel();
 
         ITmfVirtualTableModel<EventTableLine> expectedModel = new TmfVirtualTableModel<>(expectedColumnsId, expectedData, 0, 492);
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/META-INF/MANIFEST.MF b/tmf/org.eclipse.tracecompass.tmf.core/META-INF/MANIFEST.MF
index cdaa05e..a189157 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/META-INF/MANIFEST.MF
+++ b/tmf/org.eclipse.tracecompass.tmf.core/META-INF/MANIFEST.MF
@@ -35,14 +35,33 @@
    org.eclipse.tracecompass.analysis.timing.core,
    org.eclipse.tracecompass.lttng2.ust.core,
    org.eclipse.tracecompass.tmf.analysis.xml.core,
-   org.eclipse.tracecompass.analysis.counters.core",
+   org.eclipse.tracecompass.analysis.counters.core,
+   org.eclipse.tracecompass.analysis.profiling.core",
  org.eclipse.tracecompass.internal.tmf.core.model.filters;
-  x-friends:="org.eclipse.tracecompass.analysis.os.linux.core,
-   org.eclipse.tracecompass.tmf.ui,
+  x-friends:="org.eclipse.tracecompass.analysis.counters.ui,
    org.eclipse.tracecompass.analysis.graph.core,
+   org.eclipse.tracecompass.analysis.graph.ui,
+   org.eclipse.tracecompass.analysis.os.linux.core,
+   org.eclipse.tracecompass.analysis.os.linux.core.tests,
+   org.eclipse.tracecompass.analysis.os.linux.ui,
    org.eclipse.tracecompass.analysis.profiling.core,
-   org.eclipse.tracecompass.tmf.analysis.xml.core",
- org.eclipse.tracecompass.internal.tmf.core.model.timegraph;x-friends:="org.eclipse.tracecompass.analysis.os.linux.core,org.eclipse.tracecompass.tmf.analysis.xml.core,org.eclipse.tracecompass.tmf.analysis.xml.core.tests,org.eclipse.tracecompass.analysis.profiling.core",
+   org.eclipse.tracecompass.analysis.profiling.ui,
+   org.eclipse.tracecompass.analysis.timing.core,
+   org.eclipse.tracecompass.analysis.timing.ui,
+   org.eclipse.tracecompass.incubator.callstack.core,
+   org.eclipse.tracecompass.incubator.callstack.ui,
+   org.eclipse.tracecompass.tmf.analysis.xml.core,
+   org.eclipse.tracecompass.tmf.ui,
+   org.eclipse.tracecompass.tmf.core.tests,
+   org.eclipse.tracecompass.lttng2.ust.core,
+   org.eclipse.tracecompass.tmf.analysis.xml.core.tests,
+   org.eclipse.tracecompass.tmf.analysis.xml.ui,
+   org.eclipse.tracecompass.tmf.ctf.core.tests",
+ org.eclipse.tracecompass.internal.tmf.core.model.timegraph;
+  x-friends:="org.eclipse.tracecompass.analysis.os.linux.core,
+   org.eclipse.tracecompass.tmf.analysis.xml.core,
+   org.eclipse.tracecompass.tmf.analysis.xml.core.tests,
+   org.eclipse.tracecompass.analysis.profiling.core",
  org.eclipse.tracecompass.internal.tmf.core.model.tree;
   x-friends:="org.eclipse.tracecompass.analysis.os.linux.core,
    org.eclipse.tracecompass.analysis.timing.core,
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/events/Messages.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/events/Messages.java
new file mode 100644
index 0000000..58ecfc3
--- /dev/null
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/events/Messages.java
@@ -0,0 +1,36 @@
+/**********************************************************************
+ * Copyright (c) 2019 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ **********************************************************************/
+package org.eclipse.tracecompass.internal.provisional.tmf.core.model.events;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Message bundle for the new events table messages.
+ */
+public class Messages extends NLS {
+    private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.provisional.tmf.core.model.events.messages"; //$NON-NLS-1$
+    /**
+     * The events table title
+     */
+    public static @Nullable String EventsTableDataProvider_Title;
+    /**
+     * The events table data provider help text
+     */
+    public static @Nullable String EventsTableDataProviderFactory_DescriptionText;
+
+    static {
+        // initialize resource bundle
+        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+    }
+
+    private Messages() {
+        // Default constructor
+    }
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/events/TmfEventTableColumnDataModel.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/events/TmfEventTableColumnDataModel.java
index 8f9437b..dea920a 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/events/TmfEventTableColumnDataModel.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/events/TmfEventTableColumnDataModel.java
@@ -9,6 +9,7 @@
 
 package org.eclipse.tracecompass.internal.provisional.tmf.core.model.events;
 
+import java.util.List;
 import java.util.Objects;
 
 import org.eclipse.jdt.annotation.Nullable;
@@ -39,15 +40,15 @@
      *            Column ID
      * @param parentId
      *            Parent ID, -1 if no parent
-     * @param name
-     *            Column name
+     * @param columnLabels
+     *            Column labels
      * @param headerTooltip
      *            Header tooltip
      * @param isHiddenByDefault
      *            If the column should be hidden by default
      */
-    public TmfEventTableColumnDataModel(long id, long parentId, String name, String headerTooltip, boolean isHiddenByDefault) {
-        super(id, parentId, name);
+    public TmfEventTableColumnDataModel(long id, long parentId, List<String> columnLabels, String headerTooltip, boolean isHiddenByDefault) {
+        super(id, parentId, columnLabels);
         fHeaderTooltip = headerTooltip;
         fHiddenByDefault = isHiddenByDefault;
     }
@@ -87,6 +88,6 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(fHeaderTooltip, fHiddenByDefault, getId(), getName());
+        return Objects.hash(fHeaderTooltip, fHiddenByDefault, getId(), getLabels());
     }
 }
\ No newline at end of file
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 8e57d6d..31f9838 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
@@ -23,15 +23,16 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.tracecompass.internal.provisional.tmf.core.model.filters.EventTableQueryFilter;
 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;
 import org.eclipse.tracecompass.internal.provisional.tmf.core.model.table.ITmfVirtualTableDataProvider;
 import org.eclipse.tracecompass.internal.provisional.tmf.core.model.table.ITmfVirtualTableModel;
 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.filter.TmfCollapseFilter;
 import org.eclipse.tracecompass.internal.tmf.core.model.AbstractTmfTraceDataProvider;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
 import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect;
 import org.eclipse.tracecompass.tmf.core.event.aspect.TmfBaseAspects;
@@ -43,16 +44,18 @@
 import org.eclipse.tracecompass.tmf.core.filter.model.TmfFilterRootNode;
 import org.eclipse.tracecompass.tmf.core.model.CommonStatusMessage;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest;
 import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType;
+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.request.TmfEventRequest;
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.core.trace.experiment.TmfExperiment;
+
 import com.google.common.collect.ImmutableSet;
 
 /**
@@ -65,6 +68,16 @@
 public class TmfEventTableDataProvider extends AbstractTmfTraceDataProvider implements ITmfVirtualTableDataProvider<TmfEventTableColumnDataModel, EventTableLine> {
 
     /**
+     * Key for table search
+     */
+    public static final String TABLE_SEARCH_KEY = "table_search"; //$NON-NLS-1$
+
+    /**
+     * Key for table filters
+     */
+    public static final String TABLE_FILTERS_KEY = "table_filters"; //$NON-NLS-1$
+
+    /**
      * Extension point ID.
      */
     public static final String ID = "org.eclipse.tracecompass.internal.provisional.tmf.core.model.events.TmfEventTableDataProvider"; //$NON-NLS-1$
@@ -124,26 +137,43 @@
         return ID;
     }
 
+    @Deprecated
     @Override
     public TmfModelResponse<List<TmfEventTableColumnDataModel>> fetchTree(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        Map<String, Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        TmfModelResponse<TmfTreeModel<TmfEventTableColumnDataModel>> response = fetchTree(parameters, monitor);
+        TmfTreeModel<TmfEventTableColumnDataModel> model = response.getModel();
+        List<TmfEventTableColumnDataModel> treeModel = null;
+        if (model != null) {
+            treeModel = model.getEntries();
+        }
+        return new TmfModelResponse<>(treeModel, response.getStatus(), response.getStatusMessage());
+    }
+
+    @Override
+    public TmfModelResponse<TmfTreeModel<TmfEventTableColumnDataModel>> fetchTree(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         List<TmfEventTableColumnDataModel> model = new ArrayList<>();
 
         for (ITmfEventAspect<?> aspect : getTraceAspects(getTrace())) {
             synchronized (fAspectToIdMap) {
                 long id = fAspectToIdMap.computeIfAbsent(aspect, a -> fAtomicLong.getAndIncrement());
                 fIdToAspectMap.putIfAbsent(id, aspect);
-                model.add(new TmfEventTableColumnDataModel(id, -1, aspect.getName(), aspect.getHelpText(), aspect.isHiddenByDefault()));
+                model.add(new TmfEventTableColumnDataModel(id, -1, Collections.singletonList(aspect.getName()), aspect.getHelpText(), aspect.isHiddenByDefault()));
             }
         }
 
-        return new TmfModelResponse<>(model, ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
+        return new TmfModelResponse<>(new TmfTreeModel<>(Collections.emptyList(), model), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
     }
 
     @Override
-    public TmfModelResponse<ITmfVirtualTableModel<EventTableLine>> fetchLines(VirtualTableQueryFilter queryFilter, @Nullable IProgressMonitor monitor) {
-        @Nullable ITmfFilter filter = extractFilter(queryFilter);
-        @Nullable ITmfFilter searchFilter = extractSearchFilter(queryFilter);
-        @Nullable TmfCollapseFilter collapseFilter = extractCollapseFilter(queryFilter);
+    public TmfModelResponse<ITmfVirtualTableModel<EventTableLine>> fetchLines(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
+        VirtualTableQueryFilter queryFilter = FetchParametersUtils.createVirtualTableQueryFilter(fetchParameters);
+        if (queryFilter == null) {
+            return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, CommonStatusMessage.INCORRECT_QUERY_PARAMETERS);
+        }
+        @Nullable ITmfFilter filter = extractFilter(fetchParameters);
+        @Nullable ITmfFilter searchFilter = extractSearchFilter(fetchParameters);
+        @Nullable TmfCollapseFilter collapseFilter = extractCollapseFilter(fetchParameters);
         Map<Long, ITmfEventAspect<?>> aspects = getAspectsFromColumnsId(queryFilter.getColumnsId());
 
         if (aspects.isEmpty()) {
@@ -177,12 +207,12 @@
     }
 
     /**
-     * Find the index in the table of an event using the rank in the trace or the
-     * timestamp value. It will take any filter into consideration.
+     * Find the index in the table of an event using the rank in the trace or
+     * the timestamp value. It will take any filter into consideration.
      *
-     * @param queryFilter
-     *            Query filter that contain the filter applied to the table, if any.
-     *            Everything else is ignored.
+     * @param fetchParameters
+     *            Map of parameters that contain the filter applied to the
+     *            table, if any. Everything else is ignored.
      * @param traceRank
      *            Rank of the event in the trace
      * @param timeBegin
@@ -191,8 +221,8 @@
      *            Progress monitor
      * @return Index in the table
      */
-    public TmfModelResponse<List<Long>> fetchIndex(VirtualTableQueryFilter queryFilter, long traceRank, long timeBegin, @Nullable IProgressMonitor monitor) {
-        @Nullable ITmfFilter filter = extractFilter(queryFilter);
+    public TmfModelResponse<List<Long>> fetchIndex(Map<String, Object> fetchParameters, long traceRank, long timeBegin, @Nullable IProgressMonitor monitor) {
+        @Nullable ITmfFilter filter = extractFilter(fetchParameters);
         long rank;
         if (traceRank == -1) {
             ITmfContext context = getTrace().seekEvent(TmfTimestamp.fromNanos(timeBegin));
@@ -318,7 +348,7 @@
                     int lastIndex = events.size() - 1;
                     EventTableLine prevLine = events.get(lastIndex);
                     long prevRepeatCount = prevLine.getRepeatCount();
-                    events.set(lastIndex, new EventTableLine(prevLine.getLine(), prevLine.getIndex(), prevLine.getTimestamp(), prevLine.getRank(), prevRepeatCount++));
+                    events.set(lastIndex, new EventTableLine(prevLine.getCells(), prevLine.getIndex(), prevLine.getTimestamp(), prevLine.getRank(), prevRepeatCount++));
                 }
 
                 if (searchFilter != null && ((!forwardSearch && getCurrentCount() == queryCount) || events.size() == queryCount)) {
@@ -369,7 +399,7 @@
                     int lastIndex = events.size() - 1;
                     EventTableLine prevLine = events.get(lastIndex);
                     long prevRepeatCount = prevLine.getRepeatCount();
-                    events.set(lastIndex, new EventTableLine(prevLine.getLine(), prevLine.getIndex(), prevLine.getTimestamp(), prevLine.getRank(), prevRepeatCount++));
+                    events.set(lastIndex, new EventTableLine(prevLine.getCells(), prevLine.getIndex(), prevLine.getTimestamp(), prevLine.getRank(), prevRepeatCount++));
                 }
 
                 if ((searchFilter != null && !forwardSearch && getNbRead() == queryCount) || events.size() == queryCount) {
@@ -395,10 +425,11 @@
      * @return A new event table line
      */
     private static EventTableLine buildEventTableLine(Map<Long, ITmfEventAspect<?>> aspects, ITmfEvent event, long lineIndex, long lineRank) {
-        List<String> entry = new ArrayList<>(aspects.size());
+        List<VirtualTableCell> entry = new ArrayList<>(aspects.size());
         for (Entry<Long, ITmfEventAspect<?>> aspectEntry : aspects.entrySet()) {
             Object aspectResolved = aspectEntry.getValue().resolve(event);
-            entry.add(aspectResolved == null ? StringUtils.EMPTY : String.valueOf(aspectResolved));
+            String cellContent = aspectResolved == null ? StringUtils.EMPTY : String.valueOf(aspectResolved);
+            entry.add(new VirtualTableCell(cellContent));
         }
         return new EventTableLine(entry, lineIndex, event.getTimestamp(), lineRank, 0);
     }
@@ -445,13 +476,10 @@
         return fIdToAspectMap;
     }
 
-    private static @Nullable ITmfFilter extractFilter(VirtualTableQueryFilter queryFilter) {
-        if (queryFilter instanceof EventTableQueryFilter) {
-            EventTableQueryFilter eventTableQueryFilter = (EventTableQueryFilter) queryFilter;
-            ITmfFilterModel filters = eventTableQueryFilter.getFilters();
-            if (filters == null) {
-                return null;
-            }
+    private static @Nullable ITmfFilter extractFilter(Map<String, Object> fetchParameters) {
+        Object filtersObject = fetchParameters.get(TABLE_FILTERS_KEY);
+        if (filtersObject instanceof ITmfFilterModel) {
+            ITmfFilterModel filters = (ITmfFilterModel) filtersObject;
             Map<Long, String> filterMap = filters.getTableFilter();
             List<String> presetFilter = filters.getPresetFilter();
 
@@ -491,11 +519,11 @@
         return null;
     }
 
-    private static @Nullable ITmfFilter extractSearchFilter(VirtualTableQueryFilter queryFilter) {
-        if (queryFilter instanceof EventTableQueryFilter) {
-            EventTableQueryFilter eventTableQueryFilter = (EventTableQueryFilter) queryFilter;
-            Map<Long, String> searchMap = eventTableQueryFilter.getSearchFilter();
-            if (searchMap == null || searchMap.isEmpty()) {
+    private static @Nullable ITmfFilter extractSearchFilter(Map<String, Object> fetchParameters) {
+        Object searchFilterObject = fetchParameters.get(TABLE_SEARCH_KEY);
+        if (searchFilterObject instanceof Map<?, ?>) {
+            Map<Long, String> searchMap = (Map<Long, String>) searchFilterObject;
+            if (searchMap.isEmpty()) {
                 return null;
             }
 
@@ -514,10 +542,11 @@
         return null;
     }
 
-    private static @Nullable TmfCollapseFilter extractCollapseFilter(VirtualTableQueryFilter queryFilter) {
-        if (queryFilter instanceof EventTableQueryFilter) {
-            ITmfFilterModel filters = ((EventTableQueryFilter) queryFilter).getFilters();
-            if (filters != null && filters.isCollapseFilter()) {
+    private static @Nullable TmfCollapseFilter extractCollapseFilter(Map<String, Object> fetchParameters) {
+        Object filtersObject = fetchParameters.get(TABLE_FILTERS_KEY);
+        if (filtersObject instanceof ITmfFilterModel) {
+            ITmfFilterModel filters = (ITmfFilterModel) filtersObject;
+            if (filters.isCollapseFilter()) {
                 return new TmfCollapseFilter();
             }
             return null;
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/events/TmfEventTableDataProviderFactory.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/events/TmfEventTableDataProviderFactory.java
index 899d2e5..5970e7a 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/events/TmfEventTableDataProviderFactory.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/events/TmfEventTableDataProviderFactory.java
@@ -9,8 +9,15 @@
 
 package org.eclipse.tracecompass.internal.provisional.tmf.core.model.events;
 
+import java.util.Collection;
+import java.util.Collections;
+
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.common.core.NonNullUtils;
+import org.eclipse.tracecompass.internal.tmf.core.model.DataProviderDescriptor;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor.ProviderType;
 import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderFactory;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataProvider;
@@ -25,9 +32,21 @@
  */
 public class TmfEventTableDataProviderFactory implements IDataProviderFactory {
 
+    private static final IDataProviderDescriptor DESCRIPTOR =
+            new DataProviderDescriptor.Builder()
+                        .setId(TmfEventTableDataProvider.ID)
+                        .setName(NonNullUtils.nullToEmptyString(Messages.EventsTableDataProvider_Title))
+                        .setDescription(NonNullUtils.nullToEmptyString(Messages.EventsTableDataProviderFactory_DescriptionText))
+                        .setProviderType(ProviderType.TABLE)
+                        .build();
+
     @Override
     public @Nullable ITmfTreeDataProvider<? extends ITmfTreeDataModel> createProvider(@NonNull ITmfTrace trace) {
         return new TmfEventTableDataProvider(trace);
     }
 
+    @Override
+    public Collection<IDataProviderDescriptor> getDescriptors(@NonNull ITmfTrace trace) {
+        return Collections.singleton(DESCRIPTOR);
+    }
 }
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/events/messages.properties b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/events/messages.properties
new file mode 100644
index 0000000..73aec94
--- /dev/null
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/events/messages.properties
@@ -0,0 +1,11 @@
+###############################################################################
+# Copyright (c) 2019 Ericsson
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+EventsTableDataProvider_Title=Events Table
+EventsTableDataProviderFactory_DescriptionText=Show the raw events in table form for a given trace
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/filters/EventTableQueryFilter.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/filters/EventTableQueryFilter.java
index 2f183e6..5a7c008 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/filters/EventTableQueryFilter.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/filters/EventTableQueryFilter.java
@@ -12,6 +12,7 @@
 import java.util.List;
 import java.util.Map;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.internal.provisional.tmf.core.model.table.ITmfFilterModel;
 
@@ -24,6 +25,7 @@
  * @author Yonni Chen
  * @since 4.0
  */
+@NonNullByDefault
 public class EventTableQueryFilter extends VirtualTableQueryFilter {
 
     private final @Nullable Map<Long, String> fSearchFilter;
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/filters/VirtualTableQueryFilter.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/filters/VirtualTableQueryFilter.java
index 60822e4..5d4dcba 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/filters/VirtualTableQueryFilter.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/filters/VirtualTableQueryFilter.java
@@ -10,6 +10,10 @@
 package org.eclipse.tracecompass.internal.provisional.tmf.core.model.filters;
 
 import java.util.List;
+import java.util.Objects;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 
 import com.google.common.collect.ImmutableList;
 
@@ -22,6 +26,7 @@
  * @author Yonni Chen
  * @since 4.0
  */
+@NonNullByDefault
 public class VirtualTableQueryFilter {
 
     private final List<Long> fDesiredColumns;
@@ -75,4 +80,23 @@
     public long getIndex() {
         return fDesiredIndex;
     }
+
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        if (this == obj) {
+            return true;
+        }
+        VirtualTableQueryFilter other = (VirtualTableQueryFilter) obj;
+        return fDesiredColumns.equals(other.getColumnsId())
+                && fDesiredIndex == other.getIndex()
+                && fDesiredCount == other.getCount();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(fDesiredColumns, fDesiredIndex, fDesiredCount);
+    }
 }
\ No newline at end of file
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/EventTableLine.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/EventTableLine.java
index 6ec7ec4..94da90a 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/EventTableLine.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/EventTableLine.java
@@ -41,7 +41,7 @@
      * @param repeatCount
      *            Number of times this line is repeated
      */
-    public EventTableLine(List<String> data, long index, ITmfTimestamp timestamp, long rank, long repeatCount) {
+    public EventTableLine(List<VirtualTableCell> data, long index, ITmfTimestamp timestamp, long rank, long repeatCount) {
         super(index, data);
         fTimestamp = timestamp;
         fRank = rank;
@@ -78,7 +78,7 @@
     @Override
     public String toString() {
         return "Index: " + getIndex() + //$NON-NLS-1$
-                ", Line: " + getLine() + //$NON-NLS-1$
+                ", Line: " + getCells() + //$NON-NLS-1$
                 ", Timestamp: " + fTimestamp + //$NON-NLS-1$
                 ", Rank: " + fRank + //$NON-NLS-1$
                 ", RepeatCount: " + fRepeatCount; //$NON-NLS-1$
@@ -101,6 +101,6 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(fTimestamp, fRank, fRepeatCount, getIndex(), getLine());
+        return Objects.hash(fTimestamp, fRank, fRepeatCount, getIndex(), getCells());
     }
 }
\ No newline at end of file
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/ITmfVirtualTableDataProvider.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/ITmfVirtualTableDataProvider.java
index d67fa7b..39b0e65 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/ITmfVirtualTableDataProvider.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/ITmfVirtualTableDataProvider.java
@@ -9,9 +9,10 @@
 
 package org.eclipse.tracecompass.internal.provisional.tmf.core.model.table;
 
+import java.util.Map;
+
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.tracecompass.internal.provisional.tmf.core.model.filters.VirtualTableQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataProvider;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
@@ -34,8 +35,8 @@
      * This methods computes a virtual table model. Then, it returns a
      * {@link TmfModelResponse} that contains the model.
      *
-     * @param filter
-     *            A query filter that contains a list of desired columns, a starting
+     * @param fetchParameters
+     *            Query parameters that contains a list of desired columns, a starting
      *            index and a number of requested lines
      * @param monitor
      *            A ProgressMonitor to cancel task
@@ -43,5 +44,5 @@
      * @return A {@link TmfModelResponse} instance that encapsulate an
      *         {@link ITmfVirtualTableModel}
      */
-    TmfModelResponse<ITmfVirtualTableModel<L>> fetchLines(VirtualTableQueryFilter filter, @Nullable IProgressMonitor monitor);
+    TmfModelResponse<ITmfVirtualTableModel<L>> fetchLines(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor);
 }
\ No newline at end of file
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/ITmfVirtualTableModel.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/ITmfVirtualTableModel.java
index 9816935..3e7b996 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/ITmfVirtualTableModel.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/ITmfVirtualTableModel.java
@@ -34,7 +34,7 @@
      *
      * @return The list of lines
      */
-    List<L> getData();
+    List<L> getLines();
 
     /**
      * Gets the index of the first table entry in the model
@@ -49,5 +49,5 @@
      *
      * @return The total number of table entries that matches a filter
      */
-    long getNbTotalEntries();
+    long getSize();
 }
\ No newline at end of file
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/IVirtualTableLine.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/IVirtualTableLine.java
index 8606995..d9b4a54 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/IVirtualTableLine.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/IVirtualTableLine.java
@@ -30,5 +30,5 @@
      *
      * @return A list of string that contain the data for this line
      */
-    List<String> getLine();
+    List<VirtualTableCell> getCells();
 }
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/TmfVirtualTableModel.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/TmfVirtualTableModel.java
index e4004c6..7423204 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/TmfVirtualTableModel.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/TmfVirtualTableModel.java
@@ -27,9 +27,9 @@
 public class TmfVirtualTableModel<L extends VirtualTableLine> implements ITmfVirtualTableModel<L> {
 
     private final List<Long> fColumnIds;
-    private final List<L> fData;
-    private final long fIndex;
-    private final long fNbTotalEvents;
+    private final List<L> fLines;
+    private final long fLowIndex;
+    private final long fSize;
 
     /**
      * Constructor. The data passed in parameter is deep copied
@@ -45,11 +45,11 @@
      *            the total number of entries
      */
     public TmfVirtualTableModel(List<Long> columnIds, List<L> data, long index, long nbTotalEvents) {
-        fIndex = index;
+        fLowIndex = index;
         fColumnIds = ImmutableList.copyOf(columnIds);
 
-        fData = ImmutableList.copyOf(data);
-        fNbTotalEvents = nbTotalEvents;
+        fLines = ImmutableList.copyOf(data);
+        fSize = nbTotalEvents;
     }
 
     @Override
@@ -58,23 +58,23 @@
     }
 
     @Override
-    public List<L> getData() {
-        return fData;
+    public List<L> getLines() {
+        return fLines;
     }
 
     @Override
     public long getIndex() {
-        return fIndex;
+        return fLowIndex;
     }
 
     @Override
-    public long getNbTotalEntries() {
-        return fNbTotalEvents;
+    public long getSize() {
+        return fSize;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(fIndex, fNbTotalEvents, fColumnIds, fData);
+        return Objects.hash(fLowIndex, fSize, fColumnIds, fLines);
     }
 
     @Override
@@ -89,17 +89,17 @@
             return false;
         }
         TmfVirtualTableModel<?> other = (TmfVirtualTableModel<?>) obj;
-        return fIndex == other.getIndex() &&
-                fNbTotalEvents == other.getNbTotalEntries() &&
+        return fLowIndex == other.getIndex() &&
+                fSize == other.getSize() &&
                 fColumnIds.equals(other.fColumnIds) &&
-                fData.equals(other.fData);
+                fLines.equals(other.fLines);
     }
 
     @Override
     public String toString() {
         return "Column Ids: " + fColumnIds + //$NON-NLS-1$
-                ", Data: " + fData + //$NON-NLS-1$
-                ", Index: " + fIndex + //$NON-NLS-1$
-                ", Total nb of events: " + fNbTotalEvents; //$NON-NLS-1$
+                ", Data: " + fLines + //$NON-NLS-1$
+                ", Index: " + fLowIndex + //$NON-NLS-1$
+                ", Total nb of events: " + fSize; //$NON-NLS-1$
     }
 }
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/VirtualTableCell.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/VirtualTableCell.java
new file mode 100644
index 0000000..2986565
--- /dev/null
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/VirtualTableCell.java
@@ -0,0 +1,87 @@
+/**********************************************************************
+ * Copyright (c) 2019 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ **********************************************************************/
+
+package org.eclipse.tracecompass.internal.provisional.tmf.core.model.table;
+
+import java.util.Objects;
+
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * Represent a cell in a virtual table
+ *
+ * @author Simon Delisle
+ */
+public class VirtualTableCell {
+    private String fContent;
+    private int fTags;
+
+    /**
+     * Constructor
+     *
+     * @param content
+     *            Content of the cell
+     */
+    public VirtualTableCell(String content) {
+        this.fContent = content;
+        this.fTags = 0;
+    }
+
+    /**
+     * Constructor
+     *
+     * @param content
+     *            Content of the cell
+     * @param tags
+     *            Used if the cell pass a filter
+     */
+    public VirtualTableCell(String content, int tags) {
+        this.fContent = content;
+        this.fTags = tags;
+    }
+
+    /**
+     * Retrieve the content of the cell
+     *
+     * @return Content
+     */
+    public String getContent() {
+        return fContent;
+    }
+
+    /**
+     * Get tags
+     *
+     * @return Tags encode as int
+     */
+    public int getTags() {
+        return fTags;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        VirtualTableCell other = (VirtualTableCell) obj;
+        return fContent.equals(other.getContent()) &&
+                fTags == other.getTags();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(fContent, fTags);
+    }
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/VirtualTableLine.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/VirtualTableLine.java
index bc11f77..6952351 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/VirtualTableLine.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/provisional/tmf/core/model/table/VirtualTableLine.java
@@ -22,7 +22,7 @@
  */
 public class VirtualTableLine implements IVirtualTableLine {
 
-    private List<String> fLineData;
+    private List<VirtualTableCell> fCells;
     private long findex;
 
     /**
@@ -31,12 +31,12 @@
      * @param index
      *            Index for this line
      *
-     * @param lineData
+     * @param cellData
      *            Data for this line
      */
-    public VirtualTableLine(long index, List<String> lineData) {
+    public VirtualTableLine(long index, List<VirtualTableCell> cellData) {
         findex = index;
-        fLineData = lineData;
+        fCells = cellData;
     }
 
     @Override
@@ -45,8 +45,8 @@
     }
 
     @Override
-    public List<String> getLine() {
-        return fLineData;
+    public List<VirtualTableCell> getCells() {
+        return fCells;
     }
 
     @Override
@@ -61,12 +61,12 @@
             return false;
         }
         VirtualTableLine other = (VirtualTableLine) obj;
-        return fLineData.equals(other.getLine()) &&
+        return fCells.equals(other.getCells()) &&
                 findex == other.getIndex();
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(fLineData, findex);
+        return Objects.hash(fCells, findex);
     }
 }
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/histogram/HistogramDataProvider.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/histogram/HistogramDataProvider.java
index feb96d6..72e621d 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/histogram/HistogramDataProvider.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/histogram/HistogramDataProvider.java
@@ -16,6 +16,7 @@
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.concurrent.atomic.AtomicLong;
 
@@ -24,6 +25,7 @@
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.internal.tmf.core.model.AbstractTmfTraceDataProvider;
 import org.eclipse.tracecompass.internal.tmf.core.model.TmfXyResponseFactory;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
 import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
 import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
@@ -32,6 +34,7 @@
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeDataModel;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.model.xy.ITmfTreeXYDataProvider;
 import org.eclipse.tracecompass.tmf.core.model.xy.ITmfXyModel;
 import org.eclipse.tracecompass.tmf.core.model.xy.IYModel;
@@ -66,7 +69,7 @@
     private static final AtomicLong TRACE_IDS = new AtomicLong();
 
     private final TmfStatisticsModule fModule;
-    private @Nullable TmfModelResponse<List<TmfTreeDataModel>> fCached = null;
+    private @Nullable TmfModelResponse<TmfTreeModel<TmfTreeDataModel>> fCached = null;
     private final long fTraceId = TRACE_IDS.getAndIncrement();
     private final long fTotalId = TRACE_IDS.getAndIncrement();
     private final long fLostId = TRACE_IDS.getAndIncrement();
@@ -84,36 +87,58 @@
         fModule = module;
     }
 
+    @Deprecated
     @Override
     public TmfModelResponse<List<TmfTreeDataModel>> fetchTree(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        Map<String, Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        TmfModelResponse<TmfTreeModel<TmfTreeDataModel>> response = fetchTree(parameters, monitor);
+        TmfTreeModel<TmfTreeDataModel> model = response.getModel();
+        List<TmfTreeDataModel> treeModel = null;
+        if (model != null) {
+            treeModel = model.getEntries();
+        }
+        return new TmfModelResponse<>(treeModel, response.getStatus(), response.getStatusMessage());
+    }
+
+    @Deprecated
+    @Override
+    public TmfModelResponse<ITmfXyModel> fetchXY(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        Map<String, Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        return fetchXY(parameters, monitor);
+    }
+
+    @Override
+    public TmfModelResponse<TmfTreeModel<TmfTreeDataModel>> fetchTree(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         if (fCached != null) {
             return fCached;
         }
         fModule.waitForInitialization();
         Builder<TmfTreeDataModel> builder = ImmutableList.builder();
-        builder.add(new TmfTreeDataModel(fTraceId, -1, getTrace().getName()));
-        builder.add(new TmfTreeDataModel(fTotalId, fTraceId, Objects.requireNonNull(Messages.HistogramDataProvider_Total)));
+        builder.add(new TmfTreeDataModel(fTraceId, -1, Collections.singletonList(getTrace().getName())));
+        builder.add(new TmfTreeDataModel(fTotalId, fTraceId, Collections.singletonList(Objects.requireNonNull(Messages.HistogramDataProvider_Total))));
         ITmfStateSystem eventsSs = Objects.requireNonNull(fModule.getStateSystem(TmfStatisticsEventTypesModule.ID));
         if (eventsSs.optQuarkAbsolute(Attributes.LOST_EVENTS) != ITmfStateSystem.INVALID_ATTRIBUTE) {
-            builder.add(new TmfTreeDataModel(fLostId, fTraceId, Objects.requireNonNull(Messages.HistogramDataProvider_Lost)));
+            builder.add(new TmfTreeDataModel(fLostId, fTraceId, Collections.singletonList(Objects.requireNonNull(Messages.HistogramDataProvider_Lost))));
         }
         if (eventsSs.waitUntilBuilt(0)) {
-            TmfModelResponse<List<TmfTreeDataModel>> response = new TmfModelResponse<>(builder.build(), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
+            TmfModelResponse<TmfTreeModel<TmfTreeDataModel>> response = new TmfModelResponse<>(new TmfTreeModel<>(Collections.emptyList(), builder.build()), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
             fCached = response;
             return response;
         }
-        return new TmfModelResponse<>(builder.build(), ITmfResponse.Status.RUNNING, CommonStatusMessage.RUNNING);
+        return new TmfModelResponse<>(new TmfTreeModel<>(Collections.emptyList(), builder.build()), ITmfResponse.Status.RUNNING, CommonStatusMessage.RUNNING);
     }
 
     @Override
-    public @NonNull TmfModelResponse<ITmfXyModel> fetchXY(@NonNull TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public @NonNull TmfModelResponse<ITmfXyModel> fetchXY(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         fModule.waitForInitialization();
-        long[] xValues = filter.getTimesRequested();
-
-        if (!(filter instanceof SelectionTimeQueryFilter)) {
+        SelectionTimeQueryFilter filter = FetchParametersUtils.createSelectionTimeQuery(fetchParameters);
+        long[] xValues = new long[0];
+        if (filter == null) {
             return TmfXyResponseFactory.create(TITLE, xValues, Collections.emptyMap(), true);
         }
-        Collection<Long> selected = ((SelectionTimeQueryFilter) filter).getSelectedItems();
+        xValues = filter.getTimesRequested();
+
+        Collection<Long> selected = filter.getSelectedItems();
         int n = xValues.length;
         ImmutableMap.Builder<String, IYModel> builder = ImmutableMap.builder();
 
@@ -124,14 +149,14 @@
             double[] y = new double[n];
             Arrays.setAll(y, values::get);
             String totalName = getTrace().getName() + '/' + Messages.HistogramDataProvider_Total;
-            builder.put(totalName, new YModel(fTotalId, totalName, y));
+            builder.put(Long.toString(fTotalId), new YModel(fTotalId, totalName, y));
         }
 
         ITmfStateSystem eventsSs = fModule.getStateSystem(TmfStatisticsEventTypesModule.ID);
         if (selected.contains(fLostId) && eventsSs != null) {
             try {
                 YModel series = getLostEvents(eventsSs, xValues);
-                builder.put(series.getName(), series);
+                builder.put(Long.toString(series.getId()), series);
             } catch (StateSystemDisposedException e) {
                 return TmfXyResponseFactory.createFailedResponse(CommonStatusMessage.STATE_SYSTEM_FAILED);
             }
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/histogram/HistogramDataProviderFactory.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/histogram/HistogramDataProviderFactory.java
index 0f2adf0..9506f4b 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/histogram/HistogramDataProviderFactory.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/histogram/HistogramDataProviderFactory.java
@@ -10,9 +10,15 @@
 package org.eclipse.tracecompass.internal.tmf.core.histogram;
 
 import java.util.Collection;
+import java.util.Collections;
 
+import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.common.core.NonNullUtils;
+import org.eclipse.tracecompass.internal.tmf.core.model.DataProviderDescriptor;
 import org.eclipse.tracecompass.internal.tmf.core.model.xy.TmfTreeXYCompositeDataProvider;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor.ProviderType;
 import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderFactory;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
 import org.eclipse.tracecompass.tmf.core.model.xy.ITmfTreeXYDataProvider;
@@ -30,6 +36,14 @@
  */
 public class HistogramDataProviderFactory implements IDataProviderFactory {
 
+    private static final IDataProviderDescriptor DESCRIPTOR =
+            new DataProviderDescriptor.Builder()
+                        .setId(HistogramDataProvider.ID)
+                        .setName(NonNullUtils.nullToEmptyString(Messages.HistogramDataProvider_Title))
+                        .setDescription(NonNullUtils.nullToEmptyString(Messages.HistogramDataProviderFactory_DescriptionText))
+                        .setProviderType(ProviderType.TREE_TIME_XY)
+                        .build();
+
     @Override
     public @Nullable ITmfTreeXYDataProvider<? extends ITmfTreeDataModel> createProvider(ITmfTrace trace) {
         Collection<ITmfTrace> traces = TmfTraceManager.getTraceSet(trace);
@@ -43,4 +57,9 @@
         return TmfTreeXYCompositeDataProvider.create(traces, HistogramDataProvider.TITLE, HistogramDataProvider.ID);
     }
 
+    @Override
+    public Collection<IDataProviderDescriptor> getDescriptors(@NonNull ITmfTrace trace) {
+        return Collections.singletonList(DESCRIPTOR);
+    }
+
 }
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/histogram/Messages.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/histogram/Messages.java
index eab2d16..a59a3c6 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/histogram/Messages.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/histogram/Messages.java
@@ -27,6 +27,10 @@
      */
     public static @Nullable String HistogramDataProvider_Title;
     /**
+     * DataProvider help text
+     */
+    public static @Nullable String HistogramDataProviderFactory_DescriptionText;
+    /**
      * New Histogram Total events series' table
      */
     public static @Nullable String HistogramDataProvider_Total;
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/histogram/messages.properties b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/histogram/messages.properties
index d11e5ee..a84ff6a 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/histogram/messages.properties
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/histogram/messages.properties
@@ -9,7 +9,8 @@
 
 HistogramDataProvider_Lost=Lost
 HistogramDataProvider_NumberOfEvent=Number of events
-HistogramDataProvider_Title=New Histogram
+HistogramDataProvider_Title=Histogram
 HistogramDataProvider_Total=Total
+HistogramDataProviderFactory_DescriptionText=Show a histogram of number of events to time for a trace
 NewHistogramTree_ColumnName=Trace name
 NewHistogramTree_Legend=Legend
\ No newline at end of file
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/AbstractTmfTraceDataProvider.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/AbstractTmfTraceDataProvider.java
index fd5a064..9e3d010 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/AbstractTmfTraceDataProvider.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/AbstractTmfTraceDataProvider.java
@@ -17,7 +17,6 @@
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.tracecompass.internal.provisional.tmf.core.model.filter.parser.FilterCu;
 import org.eclipse.tracecompass.internal.provisional.tmf.core.model.filter.parser.IFilterStrings;
-import org.eclipse.tracecompass.internal.tmf.core.model.filters.IRegexQuery;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 
 import com.google.common.collect.Multimap;
@@ -57,12 +56,11 @@
     /**
      * Compute the predicate for every property regexes
      *
-     * @param queryFilter
-     *            The query filter holding the regexes
+     * @param regexes
+     *            Multimap holding the regexes
      * @return A map of time event filters predicate by property
      */
-    protected Map<Integer, Predicate<@NonNull Multimap<@NonNull String, @NonNull String>>> computeRegexPredicate(IRegexQuery queryFilter) {
-        Multimap<@NonNull Integer, @NonNull String> regexes = queryFilter.getRegexes();
+    protected Map<Integer, Predicate<@NonNull Multimap<@NonNull String, @NonNull String>>> computeRegexPredicate(Multimap<Integer, String> regexes) {
         Map<@NonNull Integer, @NonNull Predicate<@NonNull Multimap<@NonNull String, @NonNull String>>> predicates = new HashMap<>();
         for (Map.Entry<Integer, Collection<String>> entry : regexes.asMap().entrySet()) {
             String regex = IFilterStrings.mergeFilters(entry.getValue());
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/DataProviderDescriptor.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/DataProviderDescriptor.java
new file mode 100644
index 0000000..e82f4cc
--- /dev/null
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/DataProviderDescriptor.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.tmf.core.model;
+
+import java.util.Objects;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor;
+
+/**
+ * Data Provider description, used to list the available providers for a trace
+ * without triggering the analysis or creating the providers. Supplies
+ * information such as the extension point ID, type of provider and help text.
+ *
+ * @author Loic Prieur-Drevon
+ * @author Bernd Hufmann
+ * @since 4.3
+ */
+public class DataProviderDescriptor implements IDataProviderDescriptor {
+
+    private final String fId;
+    private final String fName;
+    private final String fDescription;
+    private final ProviderType fType;
+
+    /**
+     * Constructor
+     *
+     * @param bulider
+     *            the builder object to create the descriptor
+     */
+    private DataProviderDescriptor(Builder builder) {
+        fId = builder.fId;
+        fName = builder.fName;
+        fDescription = builder.fDescription;
+        fType = Objects.requireNonNull(builder.fType);
+    }
+
+    @Override
+    public String getName() {
+        return fName;
+    }
+
+    @Override
+    public String getId() {
+        return fId;
+    }
+
+    @Override
+    public ProviderType getType() {
+        return fType;
+    }
+
+    @Override
+    public String getDescription() {
+        return fDescription;
+    }
+
+    /**
+     * A builder class to build instances implementing interface {@link IDataProviderDescriptor}
+     */
+    public static class Builder {
+        private String fId = ""; //$NON-NLS-1$
+        private String fName = ""; //$NON-NLS-1$
+        private String fDescription = ""; //$NON-NLS-1$
+        private @Nullable ProviderType fType = null;
+
+        /**
+         * Constructor
+         */
+        public Builder() {
+            // Empty constructor
+        }
+
+        /**
+         * Sets the data provider ID
+         *
+         * @param id
+         *            the ID of the data provider
+         * @return the builder instance.
+         */
+        public Builder setId(String id) {
+            fId = id;
+            return this;
+        }
+
+        /**
+         * Sets the name of the data provider
+         *
+         * @param name
+         *            the name to set
+         * @return the builder instance.
+         */
+        public Builder setName(String name) {
+            fName = name;
+            return this;
+        }
+
+        /**
+         * Sets the description of the data provider
+         *
+         * @param description
+         *            the description text to set
+         * @return the builder instance.
+         */
+        public Builder setDescription(String description) {
+            fDescription = description;
+            return this;
+        }
+
+        /**
+         * Sets the data provider type
+         *
+         * @param type
+         *            the data provider type to set
+         * @return the builder instance.
+         */
+        public Builder setProviderType(ProviderType type) {
+            fType = type;
+            return this;
+        }
+
+        /**
+         * The method to construct an instance of
+         * {@link IDataProviderDescriptor}
+         *
+         * @return a {@link IDataProviderDescriptor} instance
+         */
+        public IDataProviderDescriptor build() {
+            if (fType == null) {
+                throw new IllegalStateException("Data provider type not set"); //$NON-NLS-1$
+            }
+            if (fId.isEmpty()) {
+                throw new IllegalStateException("Empty data provider ID"); //$NON-NLS-1$
+            }
+            return new DataProviderDescriptor(this);
+        }
+
+    }
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/TmfXyResponseFactory.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/TmfXyResponseFactory.java
index c80a3f8..d0f8da7 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/TmfXyResponseFactory.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/TmfXyResponseFactory.java
@@ -15,7 +15,7 @@
 
 import org.apache.commons.lang3.StringUtils;
 import org.eclipse.tracecompass.tmf.core.model.CommonStatusMessage;
-import org.eclipse.tracecompass.tmf.core.model.TmfCommonXAxisModel;
+import org.eclipse.tracecompass.tmf.core.model.SeriesModel;
 import org.eclipse.tracecompass.tmf.core.model.TmfXyModel;
 import org.eclipse.tracecompass.tmf.core.model.xy.ISeriesModel;
 import org.eclipse.tracecompass.tmf.core.model.xy.ITmfXyModel;
@@ -23,6 +23,8 @@
 import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 
+import com.google.common.collect.Maps;
+
 /**
  * This class creates instance of {@link TmfModelResponse}
  *
@@ -55,7 +57,9 @@
      *         completed status
      */
     public static TmfModelResponse<ITmfXyModel> create(String title, long[] xValues, Map<String, IYModel> yModels, boolean isComplete) {
-        ITmfXyModel model = new TmfCommonXAxisModel(title, xValues, yModels);
+//        ITmfXyModel model = new TmfCommonXAxisModel(title, xValues, yModels);
+        Map<String, ISeriesModel> series = Maps.transformValues(yModels, model -> new SeriesModel(model.getId(), model.getName(), xValues, model.getData()));
+        ITmfXyModel model = new TmfXyModel(title, series);
 
         if (isComplete) {
             return new TmfModelResponse<>(model, ITmfResponse.Status.COMPLETED, Objects.requireNonNull(CommonStatusMessage.COMPLETED));
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/filters/FetchParametersUtils.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/filters/FetchParametersUtils.java
new file mode 100644
index 0000000..ac39a08
--- /dev/null
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/filters/FetchParametersUtils.java
@@ -0,0 +1,165 @@
+/**********************************************************************
+ * Copyright (c) 2019 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ **********************************************************************/
+
+package org.eclipse.tracecompass.internal.tmf.core.model.filters;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.internal.provisional.tmf.core.model.filters.VirtualTableQueryFilter;
+import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
+import org.eclipse.tracecompass.tmf.core.model.filters.FilterTimeQueryFilter;
+import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
+import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
+
+/**
+ * Utility class to deal with data providers parameters. It can be use to create
+ * parameters map from the old filter's API or create filters with a map.
+ *
+ * @author Simon Delisle
+ */
+public class FetchParametersUtils {
+
+    private FetchParametersUtils() {
+        // Default constructor
+    }
+
+    /**
+     * Create a {@link TimeQueryFilter} with the given map of parameters
+     *
+     * @param parameters
+     *            Map of parameters
+     * @return A {@link TimeQueryFilter} or null if the parameters are invalid
+     */
+    public static @Nullable TimeQueryFilter createTimeQuery(Map<String, Object> parameters) {
+        List<Long> timeRequested = DataProviderParameterUtils.extractTimeRequested(parameters);
+        return timeRequested == null ? null : new TimeQueryFilter(timeRequested);
+    }
+
+    /**
+     * Create a {@link SelectionTimeQueryFilter} with the given map of parameters
+     *
+     * @param parameters
+     *            Map of parameters
+     * @return A {@link SelectionTimeQueryFilter} or null if the parameters are invalid
+     */
+    public static @Nullable SelectionTimeQueryFilter createSelectionTimeQuery(Map<String, Object> parameters) {
+        List<Long> timeRequested = DataProviderParameterUtils.extractTimeRequested(parameters);
+        List<Long> selectedItems = DataProviderParameterUtils.extractSelectedItems(parameters);
+        return (timeRequested == null || selectedItems == null) ? null : new SelectionTimeQueryFilter(timeRequested, selectedItems);
+    }
+
+    /**
+     * Create a {@link VirtualTableQueryFilter} with the given map of parameters
+     *
+     * @param parameters
+     *            Map of parameters
+     * @return A {@link VirtualTableQueryFilter} or null if the parameters are invalid
+     */
+    public static @Nullable VirtualTableQueryFilter createVirtualTableQueryFilter(Map<String, Object> parameters) {
+        List<Long> columnRequested = DataProviderParameterUtils.extractLongList(parameters, DataProviderParameterUtils.REQUESTED_COLUMN_IDS_KEY);
+        if(columnRequested == null) {
+            return null;
+        }
+
+        Object indexObject = parameters.get(DataProviderParameterUtils.REQUESTED_TABLE_INDEX_KEY);
+        if (!(indexObject instanceof Long) && !(indexObject instanceof Integer)) {
+            return null;
+        }
+
+        long index = indexObject instanceof Long ? (long) indexObject : ((Integer) indexObject).longValue();
+
+        Object countObject = parameters.get(DataProviderParameterUtils.REQUESTED_TABLE_COUNT_KEY);
+        if (!(countObject instanceof Integer)) {
+            return null;
+        }
+
+        return new VirtualTableQueryFilter(columnRequested, index, (int) countObject);
+    }
+
+    /**
+     * Convert a given {@link TimeQueryFilter} into a map of parameters
+     *
+     * @param queryFilter
+     *            The query filter
+     * @return A map of parameters
+     */
+    public static Map<String, Object> timeQueryToMap(TimeQueryFilter queryFilter) {
+        Map<String, Object> map = new HashMap<>();
+        long[] timesRequested = queryFilter.getTimesRequested();
+        List<Long> longList = new ArrayList<>();
+        for (long time : timesRequested) {
+            longList.add(time);
+        }
+        map.put(DataProviderParameterUtils.REQUESTED_TIME_KEY, longList);
+        return map;
+    }
+
+    /**
+     * Convert a given {@link SelectionTimeQueryFilter} into a map of parameters
+     *
+     * @param queryFilter
+     *            The query filter
+     * @return A map of parameters
+     */
+    public static Map<String, Object> selectionTimeQueryToMap(SelectionTimeQueryFilter queryFilter) {
+        Map<String, Object> map = new HashMap<>();
+        long[] timesRequested = queryFilter.getTimesRequested();
+        Collection<Long> selectedItems = queryFilter.getSelectedItems();
+        List<Long> longList = new ArrayList<>();
+        for (long time : timesRequested) {
+            longList.add(time);
+        }
+        map.put(DataProviderParameterUtils.REQUESTED_TIME_KEY, longList);
+        map.put(DataProviderParameterUtils.REQUESTED_ITEMS_KEY, selectedItems);
+        return map;
+    }
+
+    /**
+     * Convert a given {@link VirtualTableQueryFilter} into a map of parameters
+     *
+     * @param queryFilter
+     *            The query filter
+     * @return A map of parameters
+     */
+    public static Map<String, Object> virtualTableQueryToMap(VirtualTableQueryFilter queryFilter) {
+        Map<String, Object> map = new HashMap<>();
+        List<Long> columnsId = queryFilter.getColumnsId();
+        long index = queryFilter.getIndex();
+        int count = queryFilter.getCount();
+        map.put(DataProviderParameterUtils.REQUESTED_COLUMN_IDS_KEY, columnsId);
+        map.put(DataProviderParameterUtils.REQUESTED_TABLE_INDEX_KEY, index);
+        map.put(DataProviderParameterUtils.REQUESTED_TABLE_COUNT_KEY, count);
+        return map;
+    }
+
+    /**
+     * Convert a given {@link FilterTimeQueryFilter} into a map of parameters
+     *
+     * @param queryFilter
+     *            The query filter
+     * @return A map of parameters
+     */
+    public static Map<String, Object> filteredTimeQueryToMap(FilterTimeQueryFilter queryFilter) {
+        Map<String, Object> map = new HashMap<>();
+        long[] timesRequested = queryFilter.getTimesRequested();
+        boolean filtered = queryFilter.isFiltered();
+        List<Long> longList = new ArrayList<>();
+        for (long time : timesRequested) {
+            longList.add(time);
+        }
+        map.put(DataProviderParameterUtils.REQUESTED_TIME_KEY, longList);
+        map.put(DataProviderParameterUtils.FILTERED_KEY, filtered);
+        return map;
+    }
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/timegraph/AbstractTimeGraphDataProvider.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/timegraph/AbstractTimeGraphDataProvider.java
index 8c820df..a7faa4c 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/timegraph/AbstractTimeGraphDataProvider.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/timegraph/AbstractTimeGraphDataProvider.java
@@ -10,6 +10,7 @@
 package org.eclipse.tracecompass.internal.tmf.core.model.timegraph;
 
 import java.util.List;
+import java.util.Map;
 import java.util.logging.Level;
 
 import org.eclipse.core.runtime.IProgressMonitor;
@@ -17,6 +18,7 @@
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils.FlowScopeLog;
 import org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils.FlowScopeLogBuilder;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.internal.tmf.core.model.tree.AbstractTreeDataProvider;
 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
 import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
@@ -27,6 +29,7 @@
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphEntryModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphRowModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphStateFilter;
+import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphModel;
 import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
 import org.eclipse.tracecompass.tmf.core.response.ITmfResponse.Status;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
@@ -63,8 +66,21 @@
         super(trace, analysisModule);
     }
 
+    @Deprecated
     @Override
-    public final TmfModelResponse<List<ITimeGraphRowModel>> fetchRowModel(SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public @NonNull TmfModelResponse<List<ITimeGraphRowModel>> fetchRowModel(SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        @NonNull Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.selectionTimeQueryToMap(filter);
+        TmfModelResponse<@NonNull TimeGraphModel> response = fetchRowModel(parameters, monitor);
+        TimeGraphModel model = response.getModel();
+        List<@NonNull ITimeGraphRowModel> rows = null;
+        if (model != null) {
+            rows = model.getRows();
+        }
+        return new TmfModelResponse<>(rows, response.getStatus(), response.getStatusMessage());
+    }
+
+    @Override
+    public final TmfModelResponse<TimeGraphModel> fetchRowModel(Map<String, Object> parameters, @Nullable IProgressMonitor monitor) {
         A module = getAnalysisModule();
         if (!module.waitForInitialization()) {
             return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, CommonStatusMessage.ANALYSIS_INITIALIZATION_FAILED);
@@ -76,12 +92,17 @@
         }
 
         long currentEnd = ss.getCurrentEndTime();
+        //TODO Converting the map to a filter to see if mandatory parameters are there. This should be handle differently.
+        SelectionTimeQueryFilter filter = FetchParametersUtils.createSelectionTimeQuery(parameters);
+        if (filter == null) {
+            return new TmfModelResponse<>(null, Status.FAILED, CommonStatusMessage.INCORRECT_QUERY_PARAMETERS);
+        }
         boolean complete = ss.waitUntilBuilt(0) || filter.getEnd() <= currentEnd;
 
         try (FlowScopeLog scope = new FlowScopeLogBuilder(LOGGER, Level.FINE, "AbstractTimeGraphDataProvider#fetchRowModel") //$NON-NLS-1$
                 .setCategory(getClass().getSimpleName()).build()) {
 
-            List<ITimeGraphRowModel> models = getRowModel(ss, filter, monitor);
+            TimeGraphModel models = getRowModel(ss, parameters, monitor);
             if (models == null) {
                 // getRowModel returns null if the query was cancelled.
                 return new TmfModelResponse<>(null, ITmfResponse.Status.CANCELLED, CommonStatusMessage.TASK_CANCELLED);
@@ -106,8 +127,8 @@
      *
      * @param ss
      *            the {@link TmfStateSystemAnalysisModule}'s {@link ITmfStateSystem}
-     * @param filter
-     *            the query's filter
+     * @param parameters
+     *            the query's parameters
      * @param monitor
      *            progress monitor
      * @return the list of row models, null if the query was cancelled
@@ -115,7 +136,7 @@
      *             if the state system was closed during the query or could not be
      *             queried.
      */
-    protected abstract @Nullable List<ITimeGraphRowModel> getRowModel(ITmfStateSystem ss,
-            SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor)
+    protected abstract @Nullable TimeGraphModel getRowModel(ITmfStateSystem ss,
+            Map<String, Object> parameters, @Nullable IProgressMonitor monitor)
             throws StateSystemDisposedException;
 }
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/timegraph/TmfTimeGraphCompositeDataProvider.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/timegraph/TmfTimeGraphCompositeDataProvider.java
index b13a763..46c5d0d 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/timegraph/TmfTimeGraphCompositeDataProvider.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/timegraph/TmfTimeGraphCompositeDataProvider.java
@@ -13,7 +13,9 @@
 import java.util.Map;
 
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.internal.tmf.core.model.tree.TmfTreeCompositeDataProvider;
 import org.eclipse.tracecompass.tmf.core.model.CommonStatusMessage;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
@@ -22,6 +24,7 @@
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphDataProvider;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphEntryModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphRowModel;
+import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphModel;
 import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 
@@ -60,16 +63,16 @@
     }
 
     @Override
-    public TmfModelResponse<List<ITimeGraphRowModel>> fetchRowModel(SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public TmfModelResponse<TimeGraphModel> fetchRowModel(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         boolean isComplete = true;
         ImmutableList.Builder<ITimeGraphRowModel> series = ImmutableList.builder();
 
         for (P dataProvider : getProviders()) {
-            TmfModelResponse<List<ITimeGraphRowModel>> response = dataProvider.fetchRowModel(filter, monitor);
+            TmfModelResponse<TimeGraphModel> response = dataProvider.fetchRowModel(fetchParameters, monitor);
             isComplete &= response.getStatus() == ITmfResponse.Status.COMPLETED;
-            List<ITimeGraphRowModel> model = response.getModel();
+            TimeGraphModel model = response.getModel();
             if (model != null) {
-                series.addAll(model);
+                series.addAll(model.getRows());
             }
 
             if (monitor != null && monitor.isCanceled()) {
@@ -77,18 +80,18 @@
             }
         }
         if (isComplete) {
-            return new TmfModelResponse<>(series.build(), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
+            return new TmfModelResponse<>(new TimeGraphModel(series.build()), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
         }
-        return new TmfModelResponse<>(series.build(), ITmfResponse.Status.RUNNING, CommonStatusMessage.RUNNING);
+        return new TmfModelResponse<>(new TimeGraphModel(series.build()), ITmfResponse.Status.RUNNING, CommonStatusMessage.RUNNING);
     }
 
     @Override
-    public TmfModelResponse<List<ITimeGraphArrow>> fetchArrows(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public TmfModelResponse<List<ITimeGraphArrow>> fetchArrows(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         boolean isComplete = true;
         ImmutableList.Builder<ITimeGraphArrow> series = ImmutableList.builder();
 
         for (P dataProvider : getProviders()) {
-            TmfModelResponse<List<ITimeGraphArrow>> response = dataProvider.fetchArrows(filter, monitor);
+            TmfModelResponse<List<ITimeGraphArrow>> response = dataProvider.fetchArrows(fetchParameters, monitor);
             isComplete &= response.getStatus() == ITmfResponse.Status.COMPLETED;
             List<ITimeGraphArrow> model = response.getModel();
             if (model != null) {
@@ -106,9 +109,9 @@
     }
 
     @Override
-    public TmfModelResponse<Map<String, String>> fetchTooltip(SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public TmfModelResponse<Map<String, String>> fetchTooltip(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         for (P dataProvider : getProviders()) {
-            TmfModelResponse<Map<String, String>> response = dataProvider.fetchTooltip(filter, monitor);
+            TmfModelResponse<Map<String, String>> response = dataProvider.fetchTooltip(fetchParameters, monitor);
             Map<String, String> tooltip = response.getModel();
             if (tooltip != null) {
                 return response;
@@ -117,4 +120,31 @@
         return new TmfModelResponse<>(null, ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
     }
 
+    @Deprecated
+    @Override
+    public @NonNull TmfModelResponse<List<ITimeGraphRowModel>> fetchRowModel(SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        @NonNull Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.selectionTimeQueryToMap(filter);
+        TmfModelResponse<@NonNull TimeGraphModel> response = fetchRowModel(parameters, monitor);
+        TimeGraphModel model = response.getModel();
+        List<@NonNull ITimeGraphRowModel> rows = null;
+        if (model != null) {
+            rows = model.getRows();
+        }
+        return new TmfModelResponse<>(rows, response.getStatus(), response.getStatusMessage());
+    }
+
+    @Deprecated
+    @Override
+    public TmfModelResponse<List<ITimeGraphArrow>> fetchArrows(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        Map<String, Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        return fetchArrows(parameters, monitor);
+    }
+
+    @Deprecated
+    @Override
+    public TmfModelResponse<Map<String, String>> fetchTooltip(SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        Map<String, Object> parameters = FetchParametersUtils.selectionTimeQueryToMap(filter);
+        return fetchTooltip(parameters, monitor);
+    }
+
 }
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/tree/AbstractTreeDataProvider.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/tree/AbstractTreeDataProvider.java
index d26259a..c229024 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/tree/AbstractTreeDataProvider.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/tree/AbstractTreeDataProvider.java
@@ -26,6 +26,7 @@
 import org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils.FlowScopeLog;
 import org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils.FlowScopeLogBuilder;
 import org.eclipse.tracecompass.internal.tmf.core.model.AbstractStateSystemAnalysisDataProvider;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
 import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
 import org.eclipse.tracecompass.tmf.core.model.CommonStatusMessage;
@@ -34,6 +35,7 @@
 import org.eclipse.tracecompass.tmf.core.model.timegraph.IElementResolver;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataProvider;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule;
@@ -71,7 +73,7 @@
     private final A fAnalysisModule;
     private final ReentrantReadWriteLock fLock = new ReentrantReadWriteLock(false);
     private final BiMap<Long, Integer> fIdToQuark = HashBiMap.create();
-    private @Nullable TmfModelResponse<List<M>> fCached;
+    private @Nullable TmfModelResponse<TmfTreeModel<M>> fCached;
     private final Map<Long, Multimap<String, String>> fEntryMetadata = new HashMap<>();
 
     /**
@@ -98,7 +100,7 @@
 
     /**
      * Get (and generate if necessary) a unique id for this quark. Should be called
-     * inside {@link #getTree(ITmfStateSystem, TimeQueryFilter, IProgressMonitor)},
+     * inside {@link #getTree(ITmfStateSystem, Map, IProgressMonitor)},
      * where the write lock is held.
      *
      * @param quark
@@ -164,8 +166,21 @@
         return times;
     }
 
+    @Deprecated
     @Override
-    public final TmfModelResponse<List<M>> fetchTree(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public TmfModelResponse<List<M>> fetchTree(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        Map<String, Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        TmfModelResponse<TmfTreeModel<M>> response = fetchTree(parameters, monitor);
+        TmfTreeModel<M> treeModel = response.getModel();
+        List<M> listModel = null;
+        if (treeModel != null) {
+            listModel = treeModel.getEntries();
+        }
+        return new TmfModelResponse<>(listModel, response.getStatus(), response.getStatusMessage());
+    }
+
+    @Override
+    public final TmfModelResponse<TmfTreeModel<M>> fetchTree(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         fLock.readLock().lock();
         try {
             if (fCached != null) {
@@ -190,18 +205,18 @@
         boolean complete = ss.waitUntilBuilt(0);
         try (FlowScopeLog scope = new FlowScopeLogBuilder(LOGGER, Level.FINE, "AbstractTreeDataProvider#fetchTree") //$NON-NLS-1$
                 .setCategory(getClass().getSimpleName()).build()) {
-            List<M> tree = null;
+            TmfTreeModel<M> tree = null;
             /* Don't query empty state system */
             if (ss.getNbAttributes() > 0 && ss.getStartTime() != Long.MIN_VALUE) {
-                tree = getTree(ss, filter, monitor);
-                for (M model : tree) {
+                tree = getTree(ss, fetchParameters, monitor);
+                for (M model : tree.getEntries()) {
                     if (model instanceof IElementResolver) {
                         fEntryMetadata.put(model.getId(), ((IElementResolver) model).getMetadata());
                     }
                 }
             }
             if (complete) {
-                TmfModelResponse<List<M>> response = new TmfModelResponse<>(tree,
+                TmfModelResponse<TmfTreeModel<M>> response = new TmfModelResponse<>(tree,
                         ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
                 if (isCacheable()) {
                     fCached = response;
@@ -245,8 +260,8 @@
      *
      * @param ss
      *            the {@link TmfStateSystemAnalysisModule}'s {@link ITmfStateSystem}
-     * @param filter
-     *            the query's filter
+     * @param fetchParameters
+     *            the query's parameters
      * @param monitor
      *            progress monitor
      * @return the tree of entries
@@ -254,6 +269,6 @@
      *             if the state system was closed during the query or could not be
      *             queried.
      */
-    protected abstract List<M> getTree(ITmfStateSystem ss, TimeQueryFilter filter,
+    protected abstract TmfTreeModel<M> getTree(ITmfStateSystem ss, Map<String, Object> fetchParameters,
             @Nullable IProgressMonitor monitor) throws StateSystemDisposedException;
 }
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/tree/TmfTreeCompositeDataProvider.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/tree/TmfTreeCompositeDataProvider.java
index fca6649..684f4ef 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/tree/TmfTreeCompositeDataProvider.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/tree/TmfTreeCompositeDataProvider.java
@@ -11,16 +11,20 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderManager;
 import org.eclipse.tracecompass.tmf.core.model.CommonStatusMessage;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataProvider;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
@@ -89,17 +93,30 @@
         fId = id;
     }
 
+    @Deprecated
     @Override
     public TmfModelResponse<List<M>> fetchTree(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        Map<String, Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        TmfModelResponse<TmfTreeModel<M>> response = fetchTree(parameters, monitor);
+        TmfTreeModel<M> model = response.getModel();
+        List<M> treeModel = null;
+        if (model != null) {
+            treeModel = model.getEntries();
+        }
+        return new TmfModelResponse<>(treeModel, response.getStatus(), response.getStatusMessage());
+    }
+
+    @Override
+    public TmfModelResponse<TmfTreeModel<M>> fetchTree(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         boolean isComplete = true;
         ImmutableList.Builder<M> series = ImmutableList.builder();
 
         for (P dataProvider : fProviders) {
-            TmfModelResponse<List<M>> response = dataProvider.fetchTree(filter, monitor);
+            TmfModelResponse<TmfTreeModel<M>> response = dataProvider.fetchTree(fetchParameters, monitor);
             isComplete &= response.getStatus() == ITmfResponse.Status.COMPLETED;
-            List<M> model = response.getModel();
+            TmfTreeModel<M> model = response.getModel();
             if (model != null) {
-                series.addAll(model);
+                series.addAll(model.getEntries());
             }
 
             if (monitor != null && monitor.isCanceled()) {
@@ -107,9 +124,9 @@
             }
         }
         if (isComplete) {
-            return new TmfModelResponse<>(series.build(), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
+            return new TmfModelResponse<>(new TmfTreeModel<>(Collections.emptyList(), series.build()), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
         }
-        return new TmfModelResponse<>(series.build(), ITmfResponse.Status.RUNNING, CommonStatusMessage.RUNNING);
+        return new TmfModelResponse<>(new TmfTreeModel<>(Collections.emptyList(), series.build()), ITmfResponse.Status.RUNNING, CommonStatusMessage.RUNNING);
     }
 
     @Override
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/xy/AbstractTreeCommonXDataProvider.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/xy/AbstractTreeCommonXDataProvider.java
index b718e5a..a8e7b27 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/xy/AbstractTreeCommonXDataProvider.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/xy/AbstractTreeCommonXDataProvider.java
@@ -9,7 +9,6 @@
 
 package org.eclipse.tracecompass.internal.tmf.core.model.xy;
 
-import java.util.Collections;
 import java.util.Map;
 import java.util.Objects;
 import java.util.logging.Level;
@@ -19,6 +18,7 @@
 import org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils.FlowScopeLog;
 import org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils.FlowScopeLogBuilder;
 import org.eclipse.tracecompass.internal.tmf.core.model.TmfXyResponseFactory;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.internal.tmf.core.model.tree.AbstractTreeDataProvider;
 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
 import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
@@ -63,9 +63,25 @@
         super(trace, analysisModule);
     }
 
+    @Deprecated
     @Override
-    public final TmfModelResponse<ITmfXyModel> fetchXY(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+    public TmfModelResponse<ITmfXyModel> fetchXY(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        Map<String, Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        return fetchXY(parameters, monitor);
+    }
+
+    @Override
+    public final TmfModelResponse<ITmfXyModel> fetchXY(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         A module = getAnalysisModule();
+
+        // TODO server: Parameters validation should be handle separately. It
+        // can be either in the data provider itself or before calling it. It
+        // will avoid the creation of filters and the content of the map can be
+        // use directly.
+        SelectionTimeQueryFilter filter = FetchParametersUtils.createSelectionTimeQuery(fetchParameters);
+        if (filter == null) {
+            return TmfXyResponseFactory.createFailedResponse(CommonStatusMessage.INCORRECT_QUERY_PARAMETERS);
+        }
         TmfModelResponse<ITmfXyModel> res = verifyParameters(module, filter, monitor);
         if (res != null) {
             return res;
@@ -78,11 +94,7 @@
 
         try (FlowScopeLog scope = new FlowScopeLogBuilder(LOGGER, Level.FINE, "AbstractTreeXyDataProvider#fetchXY") //$NON-NLS-1$
                 .setCategory(getClass().getSimpleName()).build()) {
-            if (!(filter instanceof SelectionTimeQueryFilter)) {
-                return TmfXyResponseFactory.create(getTitle(), filter.getTimesRequested(), Collections.emptyMap(), complete);
-            }
-
-            Map<String, IYModel> yModels = getYModels(ss, (SelectionTimeQueryFilter) filter, monitor);
+            Map<String, IYModel> yModels = getYModels(ss, fetchParameters, monitor);
             if (yModels == null) {
                 // getModels returns null if the query was cancelled.
                 return TmfXyResponseFactory.createCancelledResponse(CommonStatusMessage.TASK_CANCELLED);
@@ -100,7 +112,7 @@
      *
      * @param ss
      *            the {@link TmfStateSystemAnalysisModule}'s {@link ITmfStateSystem}
-     * @param filter
+     * @param fetchParameters
      *            the query's filter
      * @param monitor
      *            progress monitor
@@ -110,7 +122,7 @@
      *             queried.
      */
     protected abstract @Nullable Map<String, IYModel> getYModels(ITmfStateSystem ss,
-            SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor)
+            Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor)
                     throws StateSystemDisposedException;
 
     /**
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/xy/TmfTreeXYCompositeDataProvider.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/xy/TmfTreeXYCompositeDataProvider.java
index b175fef..58aff28 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/xy/TmfTreeXYCompositeDataProvider.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/model/xy/TmfTreeXYCompositeDataProvider.java
@@ -12,12 +12,14 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.internal.tmf.core.model.TmfXyResponseFactory;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.internal.tmf.core.model.tree.TmfTreeCompositeDataProvider;
 import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderManager;
 import org.eclipse.tracecompass.tmf.core.model.CommonStatusMessage;
@@ -120,8 +122,15 @@
         return new TmfTreeXYCompositeDataProvider<>(providers, title, providerId);
     }
 
+    @Deprecated
     @Override
     public TmfModelResponse<ITmfXyModel> fetchXY(TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        Map<String, Object> parameters = FetchParametersUtils.timeQueryToMap(filter);
+        return fetchXY(parameters, monitor);
+    }
+
+    @Override
+    public TmfModelResponse<ITmfXyModel> fetchXY(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
         /**
          * <pre>
          * Response status according to the provider's reponse statuses:
@@ -134,7 +143,7 @@
          */
         List<P> providers = getProviders();
         // Get all the responses
-        Collection<TmfModelResponse<ITmfXyModel>> responses = getXyResponses(filter, monitor, providers);
+        Collection<TmfModelResponse<ITmfXyModel>> responses = getXyResponses(fetchParameters, monitor, providers);
 
         if (monitor != null && monitor.isCanceled()) {
             return TmfXyResponseFactory.createCancelledResponse(CommonStatusMessage.TASK_CANCELLED);
@@ -156,6 +165,10 @@
                     series.putAll(model.getYData());
                 }
             });
+            TimeQueryFilter filter = FetchParametersUtils.createTimeQuery(fetchParameters);
+            if (filter == null) {
+                return TmfXyResponseFactory.createFailedResponse(CommonStatusMessage.INCORRECT_QUERY_PARAMETERS);
+            }
             return TmfXyResponseFactory.create(fTitle, filter.getTimesRequested(), series.build(), isComplete);
         }
         ImmutableMap.Builder<String, ISeriesModel> series = ImmutableMap.builder();
@@ -178,10 +191,10 @@
         return null;
     }
 
-    private Collection<TmfModelResponse<ITmfXyModel>> getXyResponses(TimeQueryFilter filter, @Nullable IProgressMonitor monitor, List<P> providers) {
+    private Collection<TmfModelResponse<ITmfXyModel>> getXyResponses(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor, List<P> providers) {
         List<TmfModelResponse<ITmfXyModel>> responses = new ArrayList<>();
         for (P dataProvider : providers) {
-            TmfModelResponse<ITmfXyModel> response = dataProvider.fetchXY(filter, monitor);
+            TmfModelResponse<ITmfXyModel> response = dataProvider.fetchXY(fetchParameters, monitor);
             responses.add(response);
 
             if (monitor != null && monitor.isCanceled()) {
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/component/DataProviderConstants.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/component/DataProviderConstants.java
new file mode 100644
index 0000000..a5cbb0c
--- /dev/null
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/component/DataProviderConstants.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.tracecompass.tmf.core.component;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * Class with constants used in data providers
+ *
+ * @author Bernd Hufmann
+ * @since 5.0
+ */
+@NonNullByDefault
+public class DataProviderConstants {
+    /**
+     * Separator between data provider ID and secondary ID
+     */
+    public static final String ID_SEPARATOR = ":"; //$NON-NLS-1$
+
+    private DataProviderConstants() {
+        // Empty constructor
+    }
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/dataprovider/DataProviderManager.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/dataprovider/DataProviderManager.java
index 3164e5b..c4c0ce9 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/dataprovider/DataProviderManager.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/dataprovider/DataProviderManager.java
@@ -9,7 +9,11 @@
 
 package org.eclipse.tracecompass.tmf.core.dataprovider;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import org.eclipse.core.runtime.CoreException;
@@ -18,6 +22,7 @@
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.internal.tmf.core.Activator;
+import org.eclipse.tracecompass.tmf.core.component.DataProviderConstants;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataProvider;
 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
@@ -37,7 +42,6 @@
  */
 public class DataProviderManager {
 
-    private static final @NonNull String ID_SPLITTER = ":"; //$NON-NLS-1$
     /**
      * The singleton instance of this manager
      */
@@ -129,7 +133,7 @@
                 return dataProviderClass.cast(dataProvider);
             }
         }
-        String[] ids = id.split(ID_SPLITTER);
+        String[] ids = id.split(DataProviderConstants.ID_SEPARATOR);
         for (ITmfTrace opened : TmfTraceManager.getInstance().getOpenedTraces()) {
             if (TmfTraceManager.getTraceSetWithExperiment(opened).contains(trace)) {
                 /* if this trace or an experiment containing this trace is opened */
@@ -164,4 +168,27 @@
             }
         }).start();
     }
+
+    /**
+     * Get the list of available providers for this trace / experiment without
+     * triggering the analysis or creating the provider
+     *
+     * @param trace
+     *            queried trace
+     * @return list of the available providers for this trace / experiment
+     * @since 5.0
+     */
+    public List<IDataProviderDescriptor> getAvailableProviders(@Nullable ITmfTrace trace) {
+        if (trace == null) {
+            return Collections.emptyList();
+        }
+        List<IDataProviderDescriptor> list = new ArrayList<>();
+        for (IDataProviderFactory factory : fDataProviderFactories.values()) {
+            Collection<IDataProviderDescriptor> descriptors = factory.getDescriptors(trace);
+            if (!descriptors.isEmpty()) {
+                list.addAll(descriptors);
+            }
+        }
+        return list;
+    }
 }
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/dataprovider/DataProviderParameterUtils.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/dataprovider/DataProviderParameterUtils.java
new file mode 100644
index 0000000..8021bc2
--- /dev/null
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/dataprovider/DataProviderParameterUtils.java
@@ -0,0 +1,196 @@
+/**********************************************************************
+ * Copyright (c) 2019 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ **********************************************************************/
+
+package org.eclipse.tracecompass.tmf.core.dataprovider;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
+
+/**
+ * Utility class to deal with data providers parameters. Provides method to
+ * extract the most common parameters from a map.
+ *
+ * @author Simon Delisle
+ * @since 5.0
+ */
+@NonNullByDefault
+public class DataProviderParameterUtils {
+
+    /**
+     * Time requested key
+     */
+    public static final String REQUESTED_TIME_KEY = "requested_times"; //$NON-NLS-1$
+
+    /**
+     * Selected items key
+     */
+    public static final String REQUESTED_ITEMS_KEY = "requested_items"; //$NON-NLS-1$
+
+    /**
+     * Virtual table count key
+     */
+    public static final String REQUESTED_TABLE_COUNT_KEY = "requested_table_count"; //$NON-NLS-1$
+
+    /**
+     * Virtual table starting index key
+     */
+    public static final String REQUESTED_TABLE_INDEX_KEY = "requested_table_index"; //$NON-NLS-1$
+
+    /**
+     * Table column IDs key
+     */
+    public static final String REQUESTED_COLUMN_IDS_KEY = "requested_table_column_ids"; //$NON-NLS-1$
+
+    /**
+     * Key to extract isFiltered from parameters map
+     */
+    public static final String FILTERED_KEY = "isFiltered"; //$NON-NLS-1$
+
+    /**
+     * Regex filter key
+     */
+    public static final String REGEX_MAP_FILTERS_KEY = "regex_map_filters"; //$NON-NLS-1$
+
+    private DataProviderParameterUtils() {
+        // Private constructor
+    }
+
+    /**
+     * Extract list of Long from a map of parameters
+     *
+     * @param parameters
+     *            Map of parameters
+     * @param key
+     *            Parameter key for the value to extract
+     * @return List of Long or null if it fails to extract
+     */
+    public static @Nullable List<Long> extractLongList(Map<String, Object> parameters, String key) {
+        Object listObject = parameters.get(key);
+        if (listObject instanceof List<?>) {
+            return transformToLongList((List<?>) listObject);
+        }
+        return null;
+    }
+
+    /**
+     * Extract boolean value from a map of parameters
+     *
+     * @param parameters
+     *            Map of parameters
+     * @param key
+     *            Parameter key for the value to extract
+     * @return boolean value for this key or null if it fails to extract
+     */
+    public static @Nullable Boolean extractBoolean(Map<String, Object> parameters, String key) {
+        Object booleanObject = parameters.get(key);
+        if (booleanObject instanceof Boolean) {
+            return (Boolean) booleanObject;
+        }
+        return null;
+    }
+
+    /**
+     * Helper to extract time requested from a map of parameters
+     *
+     * @param parameters
+     *            Map of parameters
+     * @return List of times or null if no time requested in the map
+     */
+    public static @Nullable List<Long> extractTimeRequested(Map<String, Object> parameters) {
+        return extractLongList(parameters, REQUESTED_TIME_KEY);
+    }
+
+    /**
+     * Helper to extract selected items from a map of parameters
+     *
+     * @param parameters
+     *            Map of parameters
+     * @return List of selected items or null if no selected items in the map
+     */
+    public static @Nullable List<Long> extractSelectedItems(Map<String, Object> parameters) {
+        return extractLongList(parameters, REQUESTED_ITEMS_KEY);
+    }
+
+    /**
+     * Helper to extract isFiltered from a map of parameters
+     *
+     * @param parameters
+     *            Map of parameters
+     * @return True or false if it should be filtered or null if no isFiltered
+     *         parameter
+     */
+    public static @Nullable Boolean extractIsFiltered(Map<String, Object> parameters) {
+        return extractBoolean(parameters, FILTERED_KEY);
+    }
+
+    /**
+     * Helper to extract a Multimap of regexes from a map of parameters
+     *
+     * @param parameters
+     *            Map of parameters
+     * @return Multimap of regexes or null if there is no regex key in the map
+     *         of parameters
+     */
+    public static @Nullable Multimap<Integer, String> extractRegexFilter(Map<String, Object> parameters) {
+        Object regexesObject = parameters.get(REGEX_MAP_FILTERS_KEY);
+        if (!(regexesObject instanceof Map<?, ?>)) {
+            return null;
+        }
+
+        Multimap<Integer, String> regexes = HashMultimap.create();
+        Map<Integer, Collection<String>> regexesMap = (Map<Integer, Collection<String>>) regexesObject;
+        for (Entry<Integer, Collection<String>> entry : regexesMap.entrySet()) {
+            regexes.putAll(entry.getKey(), entry.getValue());
+        }
+
+        return regexes;
+    }
+
+    /**
+     * Transform a List<?> to a List<Long>, where ? is Integer or Long.
+     *
+     * @param listToTransform
+     *            List to transform
+     * @return List<Long> or null if the list can not be transformed
+     */
+    @SuppressWarnings("unchecked")
+    private static @Nullable List<Long> transformToLongList(List<?> listToTransform) {
+        if (!listToTransform.isEmpty()) {
+            if (listToTransform.stream().allMatch(e -> e instanceof Long)) {
+                return (List<Long>) listToTransform;
+            } else if (listToTransform.stream().allMatch(e -> e instanceof Integer)) {
+                List<Long> list = new ArrayList<>();
+                for (Integer element : (List<Integer>) listToTransform) {
+                    list.add(element.longValue());
+                }
+                return list;
+            } else {
+                List<Long> list = new ArrayList<>();
+                for (Object element : listToTransform) {
+                    if (!(element instanceof Number)) {
+                        return null;
+                    }
+                    list.add(((Number) element).longValue());
+                }
+                return list;
+            }
+        }
+        return Collections.emptyList();
+    }
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/dataprovider/IDataProviderDescriptor.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/dataprovider/IDataProviderDescriptor.java
new file mode 100644
index 0000000..ffdaaa6
--- /dev/null
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/dataprovider/IDataProviderDescriptor.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.tmf.core.dataprovider;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * Data Provider description, used to list the available providers for a trace
+ * without triggering the analysis or creating the providers. Supplies
+ * information such as the extension point ID, type of provider and help text.
+ *
+ * @author Loic Prieur-Drevon
+ * @author Bernd Hufmann
+ * @since 5.0
+ */
+@NonNullByDefault
+public interface IDataProviderDescriptor {
+
+    /**
+     * The type of the data provider. The purpose of the type to indicate
+     * to the clients the type of viewer to visualize or whether they can
+     * share a common x-axis (e.g. time).
+     *
+     * The following types share common x-axis/time axis:
+     *
+     * {@link #TREE_TIME_XY}
+     * {@link #TIME_GRAPH}
+     *
+     * @author Loic Prieur-Drevon
+     * @author Bernd Hufmann
+     */
+    public enum ProviderType {
+        /**
+         * A provider for a table data structure implemented as virtual table.
+         */
+        TABLE,
+        /**
+         * A provider for a tree, whose entries have XY series. The x-series is time.
+         */
+        TREE_TIME_XY,
+        /**
+         * A provider for a Time Graph model, which has entries with a start and end
+         * time, each entry has a series of states, arrows link from one series to
+         * another
+         */
+        TIME_GRAPH
+    }
+
+    /**
+     * Gets the name of the data provide
+     *
+     * @return the name
+     */
+    String getName();
+
+    /**
+     * Getter for this data provider's ID.
+     *
+     * @return the ID for this data provider.
+     */
+    String getId();
+
+    /**
+     * Getter for this data provider's type
+     *
+     * @return this data provider's type
+     */
+    ProviderType getType();
+
+    /**
+     * Getter for the description of this data provider.
+     *
+     * @return a short description of this data provider.
+     */
+    String getDescription();
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/dataprovider/IDataProviderFactory.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/dataprovider/IDataProviderFactory.java
index 22098d5..f3b6689 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/dataprovider/IDataProviderFactory.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/dataprovider/IDataProviderFactory.java
@@ -9,6 +9,9 @@
 
 package org.eclipse.tracecompass.tmf.core.dataprovider;
 
+import java.util.Collection;
+import java.util.Collections;
+
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
@@ -36,6 +39,7 @@
      */
     @Nullable ITmfTreeDataProvider<? extends ITmfTreeDataModel> createProvider(@NonNull ITmfTrace trace);
 
+
     /**
      * Create a {@link ITmfTreeDataProvider} for the given trace. If this factory
      * does not know how to handle the given trace it will return null. The
@@ -57,4 +61,19 @@
         return createProvider(trace);
     }
 
+    /**
+     * Gets the collection of data provider descriptors for this trace that this
+     * data provider factory can create, if the trace supports it, else
+     * it returns an empty list
+     *
+     * @param trace
+     *            trace whose support for this data provider we want to determine
+     * @return a collection of {@link IDataProviderDescriptor} if this trace supports this
+     *         provider, else empty list
+     * @since 5.0
+     */
+    default @NonNull Collection<IDataProviderDescriptor> getDescriptors(@NonNull ITmfTrace trace) {
+        return Collections.emptyList();
+    }
+
 }
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/CommonStatusMessage.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/CommonStatusMessage.java
index 8c8921c..7b88003 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/CommonStatusMessage.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/CommonStatusMessage.java
@@ -67,6 +67,14 @@
     public static final String INCORRECT_QUERY_INTERVAL = Objects.requireNonNull(Messages.CommonStatusMessage_IncorrectQueryInterval);
 
     /**
+     * A possible detailed message for a
+     * {@link org.eclipse.tracecompass.tmf.core.response.ITmfResponse.Status#FAILED}
+     * status
+     * @since 5.0
+     */
+    public static final String INCORRECT_QUERY_PARAMETERS = Objects.requireNonNull(Messages.CommonStatusMessage_IncorrectQueryParameters);
+
+    /**
      * Constructor
      */
     private CommonStatusMessage() {
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/Messages.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/Messages.java
index 63db171..5e0dbfb 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/Messages.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/Messages.java
@@ -51,6 +51,13 @@
      */
     public static @Nullable String CommonStatusMessage_IncorrectQueryInterval;
 
+    /**
+     * Detailed message for failed status cause by incorrect query parameters
+     *
+     * @since 5.0
+     */
+    public static @Nullable String CommonStatusMessage_IncorrectQueryParameters;
+
     static {
         // initialize resource bundle
         NLS.initializeMessages(BUNDLE_NAME, Messages.class);
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/SeriesModel.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/SeriesModel.java
index 00383fd..86a752f 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/SeriesModel.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/SeriesModel.java
@@ -9,8 +9,13 @@
 
 package org.eclipse.tracecompass.tmf.core.model;
 
+import java.util.Arrays;
+import java.util.Objects;
+
+import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.IFilterProperty;
 import org.eclipse.tracecompass.tmf.core.model.xy.ISeriesModel;
+import org.eclipse.tracecompass.tmf.core.model.xy.TmfXYAxis;
 
 import com.google.gson.annotations.SerializedName;
 
@@ -23,13 +28,33 @@
 public class SeriesModel implements ISeriesModel {
 
     /**
+     * Default name for X axis
+     */
+    private static final String DEFAULT_XAXIS_NAME = "X Axis"; //$NON-NLS-1$
+
+    /**
+     * Default unit type for X axis
+     */
+    private static final String DEFAULT_XAXIS_UNIT = "time"; //$NON-NLS-1$
+
+    /**
+     * Default name for Y axis
+     */
+    private static final String DEFAULT_YAXIS_NAME = "Y Axis"; //$NON-NLS-1$
+
+    /**
+     * Default unit type for y axis
+     */
+    private static final String DEFAULT_YAXIS_UNIT = "time"; //$NON-NLS-1$
+
+    /**
      * transient to avoid serializing for tests, as IDs may not be the same from one
      * run to the other, due to how they are generated.
      */
     @SerializedName("id")
     private final transient long fId;
 
-    @SerializedName("label")
+    @SerializedName("name")
     private final String fName;
 
     @SerializedName("xValues")
@@ -38,6 +63,15 @@
     @SerializedName("yValues")
     private final double[] fYValues;
 
+    @SerializedName("xAxis")
+    private final TmfXYAxis fXAxis;
+
+    @SerializedName("yAxis")
+    private final TmfXYAxis fYAxis;
+
+    @SerializedName("dataType")
+    private final DisplayType fDisplayType;
+
     @SerializedName("properties")
     private final int[] fProperties;
 
@@ -50,11 +84,12 @@
      *            The name of the series
      * @param xValues
      *            The x values of this series
-     * @param data
+     * @param yValues
      *            The y values of this series
+     * @since 4.2
      */
-    public SeriesModel(long id, String name, long[] xValues, double[] data) {
-        this(id, name, xValues, data, new int[xValues.length]);
+    public SeriesModel(long id, String name, long[] xValues, double[] yValues) {
+        this(id, name, xValues, yValues, new TmfXYAxis(DEFAULT_XAXIS_NAME, DEFAULT_XAXIS_UNIT), new TmfXYAxis(DEFAULT_YAXIS_NAME, DEFAULT_YAXIS_UNIT), DisplayType.LINE, new int[xValues.length]);
     }
 
     /**
@@ -66,18 +101,48 @@
      *            The name of the series
      * @param xValues
      *            The x values of this series
-     * @param data
+     * @param yValues
      *            The y values of this series
      * @param properties
      *            The properties values for this series. Some priority values
      *            are available in {@link IFilterProperty}
      * @since 4.2
+     * @deprecated Use {@link SeriesModelBuilder}
      */
-    public SeriesModel(long id, String name, long[] xValues, double[] data, int[] properties) {
+    @Deprecated
+    public SeriesModel(long id, String name, long[] xValues, double[] yValues, int[] properties) {
+        this(id, name, xValues, yValues, new TmfXYAxis(DEFAULT_XAXIS_NAME, DEFAULT_XAXIS_UNIT), new TmfXYAxis(DEFAULT_YAXIS_NAME, DEFAULT_YAXIS_UNIT), DisplayType.LINE, properties);
+    }
+
+    /**
+     * Constructor with axis description
+     *
+     * @param id
+     *            The unique ID of the associated entry
+     * @param name
+     *            The name of the series
+     * @param xValues
+     *            The x values of this series
+     * @param yValues
+     *            The y values of this series
+     * @param xAxis
+     *            X Axis description
+     * @param yAxis
+     *            Y Axis description
+     * @param displayType
+     *            Display type
+     * @param properties
+     *            The properties values for this series. Some priority values
+     *            are available in {@link IFilterProperty}
+     */
+    private SeriesModel(long id, String name, long[] xValues, double[] yValues, TmfXYAxis xAxis, TmfXYAxis yAxis, DisplayType displayType, int[] properties) {
         fId = id;
         fName = name;
         fXValues = xValues;
-        fYValues = data;
+        fYValues = yValues;
+        fXAxis = xAxis;
+        fYAxis = yAxis;
+        fDisplayType = displayType;
         fProperties = properties;
     }
 
@@ -92,6 +157,21 @@
     }
 
     @Override
+    public TmfXYAxis getXAxisDescription() {
+        return fXAxis;
+    }
+
+    @Override
+    public TmfXYAxis getYAxisDescription() {
+        return fYAxis;
+    }
+
+    @Override
+    public DisplayType getDisplayType() {
+        return fDisplayType;
+    }
+
+    @Override
     public long[] getXAxis() {
         return fXValues;
     }
@@ -105,4 +185,126 @@
     public int[] getProperties() {
         return fProperties;
     }
+
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        SeriesModel other = (SeriesModel) obj;
+        return fName.equals(other.getName())
+                && fId == other.getId()
+                && Arrays.equals(fXValues, other.getXAxis())
+                && Arrays.equals(fYValues, other.getData())
+                && fXAxis.equals(other.getXAxisDescription())
+                && fYAxis.equals(other.getYAxisDescription());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(fId, fName, fXValues, fYValues, fXAxis, fYAxis);
+    }
+
+    /**
+     * Series model builder
+     *
+     * @author Simon Delisle
+     * @since 5.0
+     */
+    public static class SeriesModelBuilder {
+        private final long id;
+        private final String name;
+        private final long[] xValues;
+        private final double[] yValues;
+        private @Nullable TmfXYAxis xAxis;
+        private @Nullable TmfXYAxis yAxis;
+        private @Nullable DisplayType displayType;
+        private int @Nullable [] properties;
+
+        /**
+         * Constructor
+         *
+         * @param id
+         *            The unique ID of the associated entry
+         * @param name
+         *            The name of the series
+         * @param xValues
+         *            The x values of this series
+         * @param yValues
+         *            The y values of this series
+         */
+        public SeriesModelBuilder(long id, String name, long[] xValues, double[] yValues) {
+            this.id = id;
+            this.name = name;
+            this.xValues = xValues;
+            this.yValues = yValues;
+        }
+
+        /**
+         * Add X axis description
+         *
+         * @param axis
+         *            Axis description
+         * @return {@link SeriesModelBuilder}
+         */
+        public SeriesModelBuilder xAxisDescription(TmfXYAxis axis) {
+            this.xAxis = axis;
+            return this;
+        }
+
+        /**
+         * Add Y axis description
+         *
+         * @param axis
+         *            Axis description
+         * @return {@link SeriesModelBuilder}
+         */
+        public SeriesModelBuilder yAxisDescription(TmfXYAxis axis) {
+            this.yAxis = axis;
+            return this;
+        }
+
+        /**
+         * Set the display type
+         *
+         * @param type
+         *            Display type
+         * @return {@link SeriesModelBuilder}
+         */
+        public SeriesModelBuilder seriesDisplayType(DisplayType type) {
+            this.displayType = type;
+            return this;
+        }
+
+        /**
+         * Set the properties
+         *
+         * @param properties
+         *            Properties
+         * @return {@link SeriesModelBuilder}
+         */
+        public SeriesModelBuilder setProperties(int[] properties) {
+            this.properties = properties;
+            return this;
+        }
+
+        /**
+         * Build a {@link SeriesModel}
+         *
+         * @return {@link SeriesModel}
+         */
+        public SeriesModel build() {
+            return new SeriesModel(id, name, xValues, yValues,
+                    xAxis != null ? xAxis : new TmfXYAxis(DEFAULT_XAXIS_NAME, DEFAULT_XAXIS_UNIT),
+                    yAxis != null ? yAxis : new TmfXYAxis(DEFAULT_YAXIS_NAME, DEFAULT_YAXIS_UNIT),
+                    displayType != null ? displayType : DisplayType.LINE,
+                    properties != null ? properties : new int[xValues.length]);
+        }
+    }
 }
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/TmfCommonXAxisModel.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/TmfCommonXAxisModel.java
index e519905..71e8238 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/TmfCommonXAxisModel.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/TmfCommonXAxisModel.java
@@ -60,7 +60,13 @@
     }
 
     @Override
+    @Deprecated
     public long[] getXAxis() {
+        return getXValues();
+    }
+
+    @Override
+    public long[] getXValues() {
         return fXValues;
     }
 
@@ -75,6 +81,11 @@
     }
 
     @Override
+    public boolean hasCommonXAxis() {
+        return true;
+    }
+
+    @Override
     public Map<String, ISeriesModel> getData() {
         return fSeries;
     }
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/TmfXyModel.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/TmfXyModel.java
index fb47aaf..9ed21c7 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/TmfXyModel.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/TmfXyModel.java
@@ -55,4 +55,9 @@
         return fSeries;
     }
 
+    @Override
+    public boolean hasCommonXAxis() {
+        return false;
+    }
+
 }
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/filters/SelectedCounterQueryFilter.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/filters/SelectedCounterQueryFilter.java
index 057f8fe..e5d2e50 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/filters/SelectedCounterQueryFilter.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/filters/SelectedCounterQueryFilter.java
@@ -10,6 +10,7 @@
 package org.eclipse.tracecompass.tmf.core.model.filters;
 
 import java.util.Collection;
+import java.util.List;
 
 /**
  * This represents a specialized query filter used by some data providers. In
@@ -45,6 +46,23 @@
         fIsCumulative = isCumulative;
     }
 
+    /**
+     * Constructor.
+     *
+     * @param times
+     *            sorted list of times to query.
+     * @param ids
+     *            The selected IDs
+     * @param isCumulative
+     *            To know if we want to fetch model as cumulative or
+     *            differential. Give true if cumulative, false either
+     * @since 5.0
+     */
+    public SelectedCounterQueryFilter(List<Long> times, Collection<Long> ids, boolean isCumulative) {
+        super(times, ids);
+        fIsCumulative = isCumulative;
+    }
+
     @Override
     public boolean isCumulative() {
         return fIsCumulative;
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/filters/SelectedCpuQueryFilter.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/filters/SelectedCpuQueryFilter.java
index 79ad37f..06d7c9b 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/filters/SelectedCpuQueryFilter.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/filters/SelectedCpuQueryFilter.java
@@ -10,6 +10,7 @@
 package org.eclipse.tracecompass.tmf.core.model.filters;
 
 import java.util.Collection;
+import java.util.List;
 import java.util.Set;
 
 import com.google.common.collect.ImmutableSet;
@@ -48,6 +49,22 @@
     }
 
     /**
+     * Constructor.
+     *
+     * @param times
+     *            Sorted list of times to query.
+     * @param selectedThreads
+     *            The selected threads
+     * @param cpu
+     *            The set of CPU
+     * @since 5.0
+     */
+    public SelectedCpuQueryFilter(List<Long> times, Collection<Long> selectedThreads, Set<Integer> cpu) {
+        super(times, selectedThreads);
+        fCpus = ImmutableSet.copyOf(cpu);
+    }
+
+    /**
      * Gets a set of selected CPUs
      *
      * @return A set of cpu id
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/filters/SelectionTimeQueryFilter.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/filters/SelectionTimeQueryFilter.java
index 14f7dec..a2a2867 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/filters/SelectionTimeQueryFilter.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/filters/SelectionTimeQueryFilter.java
@@ -11,6 +11,9 @@
 
 import java.util.Collection;
 import java.util.List;
+import java.util.Objects;
+
+import org.eclipse.jdt.annotation.Nullable;
 
 import com.google.common.collect.ImmutableList;
 
@@ -61,4 +64,21 @@
         return fItems;
     }
 
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        SelectionTimeQueryFilter other = (SelectionTimeQueryFilter) obj;
+        return fItems.equals(other.getSelectedItems());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), fItems);
+    }
+
 }
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/filters/TimeQueryFilter.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/filters/TimeQueryFilter.java
index d9289be..9758290 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/filters/TimeQueryFilter.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/filters/TimeQueryFilter.java
@@ -9,7 +9,11 @@
 
 package org.eclipse.tracecompass.tmf.core.model.filters;
 
+import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
+
+import org.eclipse.jdt.annotation.Nullable;
 
 import com.google.common.collect.Ordering;
 import com.google.common.primitives.Longs;
@@ -126,4 +130,21 @@
         result[result.length - 1] = Math.max(start, end);
         return result;
     }
+
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        if (this == obj) {
+            return true;
+        }
+        TimeQueryFilter other = (TimeQueryFilter) obj;
+        return Arrays.equals(fTimesRequested, other.getTimesRequested());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(fTimesRequested);
+    }
 }
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/messages.properties b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/messages.properties
index 3e233ec..3d1afaa 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/messages.properties
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/messages.properties
@@ -12,4 +12,5 @@
 CommonStatusMessage_TaskCancelled=Task has been cancelled
 CommonStatusMessage_AnalysisInitializationFailed=Initialization of module failed
 CommonStatusMessage_StateSystemFailed=Getting statesystem failed
-CommonStatusMessage_IncorrectQueryInterval=Incorrect query interval. Start time must be smaller than end time
\ No newline at end of file
+CommonStatusMessage_IncorrectQueryInterval=Incorrect query interval. Start time must be smaller than end time
+CommonStatusMessage_IncorrectQueryParameters=Incorrect query parameters
\ No newline at end of file
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/timegraph/ITimeGraphDataProvider.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/timegraph/ITimeGraphDataProvider.java
index 14cbc25..514510e 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/timegraph/ITimeGraphDataProvider.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/timegraph/ITimeGraphDataProvider.java
@@ -9,14 +9,18 @@
 
 package org.eclipse.tracecompass.tmf.core.model.timegraph;
 
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
+import org.eclipse.tracecompass.tmf.core.model.CommonStatusMessage;
 import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataProvider;
+import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 
 /**
@@ -43,8 +47,8 @@
 public interface ITimeGraphDataProvider<M extends ITimeGraphEntryModel> extends ITmfTreeDataProvider<M>, ITimeGraphStateFilter {
 
     /**
-     * Computes a list of time graph row models, which associate an entry's ID to
-     * sampled states.
+     * Computes a list of time graph row models, which associate an entry's ID
+     * to sampled states.
      *
      * @param filter
      *            Time graph query filter, specifies which IDs to return and the
@@ -54,10 +58,40 @@
      *
      * @return A {@link TmfModelResponse} that encapsulate a
      *         {@link ITimeGraphRowModel}
+     *
+     * @deprecated Use fetchRowModel with a map of parameters
      */
+    @Deprecated
     TmfModelResponse<List<ITimeGraphRowModel>> fetchRowModel(SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor);
 
     /**
+     * Computes a list of time graph row models, which associate an entry's ID
+     * to sampled states.
+     *
+     * @param fetchParameters
+     *            Time graph query parameters, specifies which IDs to return and
+     *            the sampling rate.
+     * @param monitor
+     *            Progress monitor
+     *
+     * @return A {@link TmfModelResponse} that encapsulate a
+     *         {@link TimeGraphModel}
+     * @since 5.0
+     */
+    default TmfModelResponse<TimeGraphModel> fetchRowModel(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
+        SelectionTimeQueryFilter filter = FetchParametersUtils.createSelectionTimeQuery(fetchParameters);
+        if (filter != null) {
+            TmfModelResponse<List<ITimeGraphRowModel>> response = fetchRowModel(filter, monitor);
+            List<ITimeGraphRowModel> rows = response.getModel();
+            if (rows != null) {
+                return new TmfModelResponse<>(new TimeGraphModel(rows), response.getStatus(), response.getStatusMessage());
+            }
+            return new TmfModelResponse<>(null, response.getStatus(), response.getStatusMessage());
+        }
+        return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, CommonStatusMessage.INCORRECT_QUERY_PARAMETERS);
+    }
+
+    /**
      * Computes a list of time graph arrows.
      *
      * @param filter
@@ -65,20 +99,69 @@
      * @param monitor
      *            Progress monitor
      *
-     * @return A {@link TmfModelResponse} that encapsulate a {@link ITimeGraphArrow}
+     * @return A {@link TmfModelResponse} that encapsulate a
+     *         {@link ITimeGraphArrow}
+     *
+     * @deprecated Use fetchArrows with a map of parameters
      */
+    @Deprecated
     TmfModelResponse<List<ITimeGraphArrow>> fetchArrows(TimeQueryFilter filter, @Nullable IProgressMonitor monitor);
 
     /**
+     * Computes a list of time graph arrows.
+     *
+     * @param fetchParameters
+     *            Query parameters, specifies the sampling rate.
+     * @param monitor
+     *            Progress monitor
+     *
+     * @return A {@link TmfModelResponse} that encapsulate a
+     *         {@link ITimeGraphArrow}
+     * @since 5.0
+     */
+    default TmfModelResponse<List<ITimeGraphArrow>> fetchArrows(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
+        TimeQueryFilter filter = FetchParametersUtils.createTimeQuery(fetchParameters);
+        if (filter != null) {
+            return fetchArrows(filter, monitor);
+        }
+
+        return new TmfModelResponse<>(Collections.emptyList(), ITmfResponse.Status.FAILED, CommonStatusMessage.INCORRECT_QUERY_PARAMETERS);
+    }
+
+    /**
      * Computes a tool tip for a time stamp and entry.
      *
      * @param filter
-     *            Time query filter, specifies the time stamp, and item on which to
+     *            Time query filter, specifies the time stamp, and item on which
+     *            to give more information
+     * @param monitor
+     *            Progress monitor
+     *
+     * @return A {@link TmfModelResponse} that encapsulate a map of Tooltips
+     *
+     * @deprecated Use fetchTooltip with a map of parameters
+     */
+    @Deprecated
+    TmfModelResponse<Map<String, String>> fetchTooltip(SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor);
+
+    /**
+     * Computes a tool tip for a time stamp and entry.
+     *
+     * @param fetchParameters
+     *            Query parameters, specifies the timestamp and item on which to
      *            give more information
      * @param monitor
      *            Progress monitor
      *
      * @return A {@link TmfModelResponse} that encapsulate a map of Tooltips
+     * @since 5.0
      */
-    TmfModelResponse<Map<String, String>> fetchTooltip(SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor);
+    default TmfModelResponse<Map<String, String>> fetchTooltip(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
+        SelectionTimeQueryFilter filter = FetchParametersUtils.createSelectionTimeQuery(fetchParameters);
+        if (filter != null) {
+            return fetchTooltip(filter, monitor);
+        }
+
+        return new TmfModelResponse<>(Collections.emptyMap(), ITmfResponse.Status.FAILED, CommonStatusMessage.INCORRECT_QUERY_PARAMETERS);
+    }
 }
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/timegraph/TimeGraphEntryModel.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/timegraph/TimeGraphEntryModel.java
index 4cfa88f..014f9c3 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/timegraph/TimeGraphEntryModel.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/timegraph/TimeGraphEntryModel.java
@@ -9,6 +9,9 @@
 
 package org.eclipse.tracecompass.tmf.core.model.timegraph;
 
+import java.util.Collections;
+import java.util.List;
+
 import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeDataModel;
 
 /**
@@ -37,10 +40,7 @@
      *            End time
      */
     public TimeGraphEntryModel(long id, long parentId, String name, long startTime, long endTime) {
-        super(id, parentId, name);
-        fStartTime = startTime;
-        fEndTime = endTime;
-        fHasRowModel = true;
+        this(id, parentId, Collections.singletonList(name), startTime, endTime, true);
     }
 
     /**
@@ -60,7 +60,47 @@
      *            true if the entry has a row model
      */
     public TimeGraphEntryModel(long id, long parentId, String name, long startTime, long endTime, boolean hasRowModel) {
-        super(id, parentId, name);
+        this(id, parentId, Collections.singletonList(name), startTime, endTime, hasRowModel);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param id
+     *            Entry ID
+     * @param parentId
+     *            Parent ID
+     * @param labels
+     *            Entry labels to be displayed
+     * @param startTime
+     *            Start time
+     * @param endTime
+     *            End time
+     * @since 5.0
+     */
+    public TimeGraphEntryModel(long id, long parentId, List<String> labels, long startTime, long endTime) {
+        this(id, parentId, labels, startTime, endTime, true);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param id
+     *            Entry ID
+     * @param parentId
+     *            Parent ID
+     * @param labels
+     *            Entry labels to be displayed
+     * @param startTime
+     *            Start time
+     * @param endTime
+     *            End time
+     * @param hasRowModel
+     *            true if the entry has a row model
+     * @since 5.0
+     */
+    public TimeGraphEntryModel(long id, long parentId, List<String> labels, long startTime, long endTime, boolean hasRowModel) {
+        super(id, parentId, labels);
         fStartTime = startTime;
         fEndTime = endTime;
         fHasRowModel = hasRowModel;
@@ -83,7 +123,7 @@
 
 @Override
     public String toString() {
-        return "<name=" + getName() + " id=" + getId() + " parentId=" + getParentId() //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        return "<name=" + getLabels() + " id=" + getId() + " parentId=" + getParentId() //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                 + " start=" + fStartTime + " end=" + fEndTime + " hasRowModel=" + hasRowModel() + ">"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
     }
 }
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/timegraph/TimeGraphModel.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/timegraph/TimeGraphModel.java
new file mode 100644
index 0000000..eafb579
--- /dev/null
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/timegraph/TimeGraphModel.java
@@ -0,0 +1,41 @@
+/**********************************************************************
+ * Copyright (c) 2019 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ **********************************************************************/
+
+package org.eclipse.tracecompass.tmf.core.model.timegraph;
+
+import java.util.List;
+
+/**
+ * Represent an entire Time Graph model
+ *
+ * @author Simon Delisle
+ * @since 5.0
+ */
+public class TimeGraphModel {
+    private List<ITimeGraphRowModel> fRows;
+
+    /**
+     * Constructor
+     *
+     * @param rows
+     *            List of {@link ITimeGraphRowModel}
+     */
+    public TimeGraphModel(List<ITimeGraphRowModel> rows) {
+        fRows = rows;
+    }
+
+    /**
+     * Get rows associated to the model
+     *
+     * @return List of {@link ITimeGraphRowModel}
+     */
+    public List<ITimeGraphRowModel> getRows() {
+        return fRows;
+    }
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/tree/ITmfTreeDataModel.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/tree/ITmfTreeDataModel.java
index 24274e5..1e77575 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/tree/ITmfTreeDataModel.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/tree/ITmfTreeDataModel.java
@@ -9,6 +9,9 @@
 
 package org.eclipse.tracecompass.tmf.core.model.tree;
 
+import java.util.Collections;
+import java.util.List;
+
 /**
  * Model's interface that can be used to represent a hierarchical relationship,
  * for instance a tree
@@ -33,9 +36,24 @@
     long getParentId();
 
     /**
-     * Returns the name of this model.
+     * Returns the name of this model. The name is a single label for this model
+     * and it is similar to getLabels(). The goal of this method is to provide
+     * an simpler way of dealing with label if this model is used in a context
+     * where there is no columns support.
      *
      * @return the model name
      */
     String getName();
+
+    /**
+     * Returns a list of labels. Each label in this list can be use as a value
+     * for columns. If there is no plan for column you can use getName() to
+     * simplify things.
+     *
+     * @return the model name
+     * @since 5.0
+     */
+    default List<String> getLabels() {
+        return Collections.singletonList(getName());
+    }
 }
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/tree/ITmfTreeDataProvider.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/tree/ITmfTreeDataProvider.java
index 0e27ef2..c89b630 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/tree/ITmfTreeDataProvider.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/tree/ITmfTreeDataProvider.java
@@ -9,11 +9,16 @@
 
 package org.eclipse.tracecompass.tmf.core.model.tree;
 
+import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
+import org.eclipse.tracecompass.tmf.core.model.CommonStatusMessage;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
+import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 
 /**
@@ -29,19 +34,50 @@
 
     /**
      * This methods computes a tree model. Then, it returns a
-     * {@link TmfModelResponse} that contains the model. Tree model will be used by
-     * tree viewer to show entries as a tree or flat hierarchy
+     * {@link TmfModelResponse} that contains the model. Tree model will be used
+     * by tree viewer to show entries as a tree or flat hierarchy
      *
      * @param filter
-     *            A query filter that contains an array of time. Times are used for
-     *            requesting data.
+     *            A query filter that contains an array of time. Times are used
+     *            for requesting data.
      * @param monitor
      *            A ProgressMonitor to cancel task
      * @return A {@link TmfModelResponse} instance
+     *
+     * @deprecated Use fetchTree with a map of parameters
      */
+    @Deprecated
     TmfModelResponse<List<T>> fetchTree(TimeQueryFilter filter, @Nullable IProgressMonitor monitor);
 
     /**
+     * This methods computes a tree model. Then, it returns a
+     * {@link TmfModelResponse} that contains the model. Tree model will be used
+     * by tree viewer to show entries as a tree or flat hierarchy
+     *
+     * @param fetchParameters
+     *            A query filter that contains an array of time. Times are used
+     *            for requesting data.
+     * @param monitor
+     *            A ProgressMonitor to cancel task
+     * @return A {@link TmfModelResponse} instance
+     * @since 5.0
+     */
+    default TmfModelResponse<TmfTreeModel<T>> fetchTree(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
+        TimeQueryFilter filter = FetchParametersUtils.createTimeQuery(fetchParameters);
+        if (filter != null) {
+            TmfModelResponse<List<T>> response = fetchTree(filter, monitor);
+            TmfTreeModel<T> model = null;
+            List<T> entryModel = response.getModel();
+            if (entryModel != null) {
+                model = new TmfTreeModel<>(Collections.emptyList(), entryModel);
+            }
+            return new TmfModelResponse<>(model, response.getStatus(), response.getStatusMessage());
+        }
+
+        return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, CommonStatusMessage.INCORRECT_QUERY_PARAMETERS);
+    }
+
+    /**
      * This method return the extension point ID of this provider
      *
      * @return The ID
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/tree/TmfTreeDataModel.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/tree/TmfTreeDataModel.java
index 2116880..ea7feba 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/tree/TmfTreeDataModel.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/tree/TmfTreeDataModel.java
@@ -9,6 +9,8 @@
 
 package org.eclipse.tracecompass.tmf.core.model.tree;
 
+import java.util.Collections;
+import java.util.List;
 import java.util.Objects;
 
 import org.eclipse.jdt.annotation.Nullable;
@@ -23,7 +25,7 @@
 
     private final long fId;
     private final long fParentId;
-    private final String fName;
+    private final List<String> fLabels;
 
     /**
      * Constructor
@@ -36,9 +38,24 @@
      *            The name of this model
      */
     public TmfTreeDataModel(long id, long parentId, String name) {
+        this(id, parentId, Collections.singletonList(name));
+    }
+
+    /**
+     * Constructor
+     *
+     * @param id
+     *            The id of the model
+     * @param parentId
+     *            The parent id of this model. If it has none, give <code>-1</code>.
+     * @param labels
+     *            The name of this model
+     * @since 5.0
+     */
+    public TmfTreeDataModel(long id, long parentId, List<String> labels) {
         fId = id;
         fParentId = parentId;
-        fName = name;
+        fLabels = labels;
     }
 
     @Override
@@ -53,7 +70,12 @@
 
     @Override
     public String getName() {
-        return fName;
+        return fLabels.isEmpty() ? "" : fLabels.get(0); //$NON-NLS-1$
+    }
+
+    @Override
+    public List<String> getLabels() {
+        return fLabels;
     }
 
     @Override
@@ -70,16 +92,16 @@
         TmfTreeDataModel other = (TmfTreeDataModel) obj;
         return fId == other.fId
                 && fParentId == other.fParentId
-                && fName.equals(other.fName);
+                && fLabels.equals(other.fLabels);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(fId, fParentId, fName);
+        return Objects.hash(fId, fParentId, fLabels);
     }
 
     @Override
     public String toString() {
-        return "<name=" + fName + " id=" + fId + " parentId=" + fParentId + ">"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+        return "<name=" + fLabels + " id=" + fId + " parentId=" + fParentId + ">"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
     }
 }
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/tree/TmfTreeModel.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/tree/TmfTreeModel.java
new file mode 100644
index 0000000..bf9e500
--- /dev/null
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/tree/TmfTreeModel.java
@@ -0,0 +1,56 @@
+/**********************************************************************
+ * Copyright (c) 2019 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ **********************************************************************/
+
+package org.eclipse.tracecompass.tmf.core.model.tree;
+
+import java.util.List;
+
+/**
+ * Represent an entire tree model
+ *
+ * @author Simon Delisle
+ * @param <T>
+ *            Tree data model extending {@link ITmfTreeDataModel}
+ * @since 5.0
+ */
+public class TmfTreeModel<T extends ITmfTreeDataModel> {
+    private List<String> fHeaders;
+    private List<T> fEntries;
+
+    /**
+     * Constructor
+     *
+     * @param headers
+     *            List of string that represent the header of a column
+     * @param entries
+     *            List of entries in the tree
+     */
+    public TmfTreeModel(List<String> headers, List<T> entries) {
+        fHeaders = headers;
+        fEntries = entries;
+    }
+
+    /**
+     * Headers for the model
+     *
+     * @return List of name of the header
+     */
+    public List<String> getHeaders() {
+        return fHeaders;
+    }
+
+    /**
+     * Entries for the model
+     *
+     * @return List of entries
+     */
+    public List<T> getEntries() {
+        return fEntries;
+    }
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/xy/ISeriesModel.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/xy/ISeriesModel.java
index ed0ad2f..9bbda6b 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/xy/ISeriesModel.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/xy/ISeriesModel.java
@@ -23,6 +23,27 @@
 public interface ISeriesModel {
 
     /**
+     * Series data type
+     *
+     * @author Simon Delisle
+     * @since 5.0
+     */
+    public enum DisplayType {
+        /**
+         * Line
+         */
+        LINE,
+        /**
+         * Scatter
+         */
+        SCATTER,
+        /**
+         * Area
+         */
+        AREA
+    }
+
+    /**
      * Get the unique ID for the entry associated to this series.
      *
      * @return the unique ID.
@@ -37,6 +58,38 @@
     String getName();
 
     /**
+     * Get the X axis description
+     *
+     * @return X Axis description
+     * @since 5.0
+     */
+    @SuppressWarnings("nls")
+    default TmfXYAxis getXAxisDescription() {
+        return new TmfXYAxis("X Axis", "");
+    }
+
+    /**
+     * Get the Y axis description
+     *
+     * @return Y Axis description
+     * @since 5.0
+     */
+    @SuppressWarnings("nls")
+    default TmfXYAxis getYAxisDescription() {
+        return new TmfXYAxis("Y Axis", "");
+    }
+
+    /**
+     * Get the display type
+     *
+     * @return Type of display (eg. line, scatter, ...)
+     * @since 5.0
+     */
+    default DisplayType getDisplayType() {
+        return DisplayType.LINE;
+    }
+
+    /**
      * Get the X values
      *
      * @return The x values
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/xy/ITmfCommonXAxisModel.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/xy/ITmfCommonXAxisModel.java
index 8f69e07..38b671a 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/xy/ITmfCommonXAxisModel.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/xy/ITmfCommonXAxisModel.java
@@ -43,7 +43,19 @@
      * Get the X values
      *
      * @return The x values
+     * @since 5.0
      */
+    default long[] getXValues() {
+        return getXAxis();
+    }
+
+    /**
+     * Get the X values
+     *
+     * @return The x values
+     * @deprecated Use getXValues instead
+     */
+    @Deprecated
     long[] getXAxis();
 
     /**
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/xy/ITmfXYDataProvider.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/xy/ITmfXYDataProvider.java
index 80c09a7..44841a5 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/xy/ITmfXYDataProvider.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/xy/ITmfXYDataProvider.java
@@ -9,9 +9,13 @@
 
 package org.eclipse.tracecompass.tmf.core.model.xy;
 
+import java.util.Map;
+
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.internal.tmf.core.model.TmfXyResponseFactory;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
+import org.eclipse.tracecompass.tmf.core.model.CommonStatusMessage;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 
@@ -36,6 +40,32 @@
      * @param monitor
      *            A ProgressMonitor to cancel task
      * @return A {@link TmfModelResponse} instance
+     *
+     * @deprecated Use fetchXY with a map of parameters
      */
+    @Deprecated
     TmfModelResponse<ITmfXyModel> fetchXY(TimeQueryFilter filter, @Nullable IProgressMonitor monitor);
+
+    /**
+     * This methods computes a XY model. Then, it returns a
+     * {@link TmfModelResponse} that contains the model. XY model will be used
+     * to draw XY charts. See {@link TmfXyResponseFactory} methods for creating
+     * {@link TmfModelResponse}.
+     *
+     * @param fetchParameters
+     *            Query parameters that contains an array of time. Times are
+     *            used for requesting data.
+     * @param monitor
+     *            A ProgressMonitor to cancel task
+     * @return A {@link TmfModelResponse} instance
+     * @since 5.0
+     */
+    default TmfModelResponse<ITmfXyModel> fetchXY(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
+        TimeQueryFilter filter = FetchParametersUtils.createTimeQuery(fetchParameters);
+        if (filter != null) {
+            return fetchXY(filter, monitor);
+        }
+
+        return TmfXyResponseFactory.createFailedResponse(CommonStatusMessage.INCORRECT_QUERY_PARAMETERS);
+    }
 }
\ No newline at end of file
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/xy/ITmfXyModel.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/xy/ITmfXyModel.java
index 9a3d22b..e0df415 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/xy/ITmfXyModel.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/xy/ITmfXyModel.java
@@ -37,9 +37,20 @@
     @Nullable String getTitle();
 
     /**
+     * True if the x values of the series are common
+     *
+     * @return True if X values are common
+     * @since 5.0
+     */
+    default boolean hasCommonXAxis() {
+        return false;
+    }
+
+    /**
      * Get the collection of {@link ISeriesModel}
      *
-     * @return the collection of series data.
+     * @return Map of series data where the key is the unique id of the
+     *         associated series
      */
     Map<String, ISeriesModel> getData();
 
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/xy/TmfXYAxis.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/xy/TmfXYAxis.java
new file mode 100644
index 0000000..3195bfa
--- /dev/null
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/xy/TmfXYAxis.java
@@ -0,0 +1,78 @@
+/**********************************************************************
+ * Copyright (c) 2019 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ **********************************************************************/
+
+package org.eclipse.tracecompass.tmf.core.model.xy;
+
+import java.util.Objects;
+
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * Represent a XY Axis model
+ *
+ * @author Simon Delisle
+ * @since 5.0
+ */
+public class TmfXYAxis {
+    private String fLabel;
+    private String fUnit;
+
+    /**
+     * Constructor
+     *
+     * @param label
+     *            Label for the axis
+     * @param unit
+     *            Unit type
+     */
+    public TmfXYAxis(String label, String unit) {
+        super();
+        fLabel = label;
+        fUnit = unit;
+    }
+
+    /**
+     * Get the axis label
+     *
+     * @return Label
+     */
+    public String getLabel() {
+        return fLabel;
+    }
+
+    /**
+     * Get the unit type
+     *
+     * @return Unit type
+     */
+    public String getUnit() {
+        return fUnit;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        TmfXYAxis other = (TmfXYAxis) obj;
+        return fLabel.equals(other.getLabel())
+                && fUnit.equals(other.getUnit());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(fLabel, fUnit);
+    }
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfTrace.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfTrace.java
index da1170e..b553d57 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfTrace.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/ITmfTrace.java
@@ -540,4 +540,14 @@
         String traceTypeId = getTraceTypeId();
         long initialTimeRange = traceTypeId != null ? TraceTypePreferences.getInitialTimeRange(traceTypeId, getInitialRangeOffset().toNanos()) : getInitialRangeOffset().toNanos();
         return new TmfTimeRange(startTime, TmfTimestamp.fromNanos(SaturatedArithmetic.add(startTime.toNanos(), initialTimeRange)));    }
+
+    /**
+     * Get the indexing status of trace
+     *
+     * @return True if the trace is still being indexed, false if not
+     * @since 5.0
+     */
+    public default boolean isIndexing() {
+        return false;
+    }
 }
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfTrace.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfTrace.java
index 205113c..f94a530 100644
--- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfTrace.java
+++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfTrace.java
@@ -422,6 +422,11 @@
         return this.getName();
     }
 
+    @Override
+    public boolean isIndexing() {
+        return fIndexer.isIndexing();
+    }
+
     // ------------------------------------------------------------------------
     // Convenience setters
     // ------------------------------------------------------------------------
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/views/XYChartViewStub.java b/tmf/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/views/XYChartViewStub.java
index ec3ab57..07a03f6 100644
--- a/tmf/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/views/XYChartViewStub.java
+++ b/tmf/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/views/XYChartViewStub.java
@@ -12,18 +12,22 @@
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.tracecompass.internal.tmf.core.model.TmfXyResponseFactory;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
+import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
 import org.eclipse.tracecompass.tmf.core.model.CommonStatusMessage;
 import org.eclipse.tracecompass.tmf.core.model.YModel;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataProvider;
 import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeDataModel;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.model.xy.ITmfTreeXYDataProvider;
 import org.eclipse.tracecompass.tmf.core.model.xy.ITmfXYDataProvider;
 import org.eclipse.tracecompass.tmf.core.model.xy.ITmfXyModel;
@@ -42,6 +46,7 @@
 import org.eclipse.tracecompass.tmf.ui.views.TmfChartView;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.primitives.Longs;
 
 /**
  * XYChart View Stub
@@ -85,30 +90,55 @@
     }
 
     private class MyTmfXyDataProvider implements ITmfTreeXYDataProvider<@NonNull ITmfTreeDataModel> {
+        @SuppressWarnings("null")
         @Override
-        public @NonNull TmfModelResponse<@NonNull ITmfXyModel> fetchXY(@NonNull TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
-            long[] xValues = filter.getTimesRequested();
-            double[] yValues = new double[xValues.length];
+        public final TmfModelResponse<ITmfXyModel> fetchXY(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
+            List<Long> xValues = DataProviderParameterUtils.extractTimeRequested(fetchParameters);
+            if (xValues == null) {
+                return TmfXyResponseFactory.createFailedResponse("No requested time values provided");
+            }
+            double[] yValues = new double[xValues.size()];
             for (int i = 0; i < yValues.length; i++) {
-                yValues[i] = xValues[i] * 0.000001;
+                yValues[i] = xValues.get(i) * 0.000001;
             }
             @NonNull
             IYModel series = new YModel(1, "Top", yValues);
-            Map<@NonNull String, @NonNull IYModel> yModels = Collections.singletonMap(series.getName(), series);
-            return TmfXyResponseFactory.create("Top", filter.getTimesRequested(), yModels, true);
+            Map<@NonNull String, @NonNull IYModel> yModels = Collections.singletonMap(Long.toString(series.getId()), series);
+            return TmfXyResponseFactory.create("Top", Objects.requireNonNull(Longs.toArray(xValues)), yModels, true);
         }
 
         @Override
-        public @NonNull TmfModelResponse<@NonNull List<@NonNull ITmfTreeDataModel>> fetchTree(@NonNull TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+        public final TmfModelResponse<TmfTreeModel<@NonNull ITmfTreeDataModel>> fetchTree(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
             @NonNull
             List<@NonNull ITmfTreeDataModel> list = Collections.singletonList(new TmfTreeDataModel(1, -1L, "Top"));
-            return new TmfModelResponse<>(list, ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
+            TmfTreeModel<@NonNull ITmfTreeDataModel> tree = new TmfTreeModel<>(Collections.emptyList(), list);
+            return new TmfModelResponse<>(tree, ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
         }
 
         @Override
         public @NonNull String getId() {
             return PROVIDER_ID;
         }
+
+        @SuppressWarnings("null")
+        @Deprecated
+        @Override
+        public @NonNull TmfModelResponse<@NonNull ITmfXyModel> fetchXY(@NonNull TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+            @NonNull Map<@NonNull String, @NonNull Object> fetchParameters = FetchParametersUtils.timeQueryToMap(filter);
+            return fetchXY(fetchParameters, monitor);
+        }
+
+        @Deprecated
+        @Override
+        public @NonNull TmfModelResponse<@NonNull List<@NonNull ITmfTreeDataModel>> fetchTree(@NonNull TimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
+            @NonNull Map<@NonNull String, @NonNull Object> fetchParameters = FetchParametersUtils.timeQueryToMap(filter);
+            TmfModelResponse<TmfTreeModel<@NonNull ITmfTreeDataModel>> response = fetchTree(fetchParameters, monitor);
+            TmfTreeModel<@NonNull ITmfTreeDataModel> tree = response.getModel();
+            if (tree == null) {
+                return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, CommonStatusMessage.STATE_SYSTEM_FAILED);
+            }
+            return new TmfModelResponse<>(tree.getEntries(), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
+        }
     }
 
     private class MyAbsractSelectTreeViewer extends AbstractSelectTreeViewer {
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/AbstractSelectTreeViewer.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/AbstractSelectTreeViewer.java
index 8758529..cfa3dc5 100644
--- a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/AbstractSelectTreeViewer.java
+++ b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/tree/AbstractSelectTreeViewer.java
@@ -45,12 +45,14 @@
 import org.eclipse.tracecompass.common.core.log.TraceCompassLog;
 import org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils.FlowScopeLog;
 import org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils.FlowScopeLogBuilder;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.internal.tmf.ui.Activator;
 import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderManager;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
 import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataProvider;
 import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeDataModel;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
@@ -297,21 +299,21 @@
                             return Status.OK_STATUS;
                         }
 
-                        TimeQueryFilter filter = getFilter(start, end, isSelection);
-                        if (filter == null) {
+                        Map<String, Object> parameters = getParameters(start, end, isSelection);
+                        if (parameters.isEmpty()) {
                             return Status.OK_STATUS;
                         }
 
                         boolean isComplete = false;
                         do {
-                            TmfModelResponse<@NonNull List<@NonNull ITmfTreeDataModel>> response;
+                            TmfModelResponse<@NonNull TmfTreeModel<@NonNull ITmfTreeDataModel>> response;
                             try (FlowScopeLog iterScope = new FlowScopeLogBuilder(LOGGER, Level.FINE, UPDATE_CONTENT_JOB_NAME + " query") //$NON-NLS-1$
                                     .setParentScope(scope).build()) {
 
-                                response = provider.fetchTree(filter, monitor);
-                                List<@NonNull ITmfTreeDataModel> model = response.getModel();
+                                response = provider.fetchTree(parameters, monitor);
+                                TmfTreeModel<@NonNull ITmfTreeDataModel> model = response.getModel();
                                 if (model != null) {
-                                    updateTree(trace, start, end, model);
+                                    updateTree(trace, start, end, model.getEntries());
                                 }
                             }
 
@@ -494,12 +496,31 @@
      *            if the query is a selection
      * @return the resulting query filter
      * @since 4.0
+     * @deprecated Use getParameters instead
      */
+    @Deprecated
     protected @Nullable TimeQueryFilter getFilter(long start, long end, boolean isSelection) {
         return new TimeQueryFilter(Long.min(start, end), Long.max(start, end), 2);
     }
 
     /**
+     * Get the map to query the {@link ITmfTreeDataProvider} for the queried
+     * parameters
+     *
+     * @param start
+     *            query start time
+     * @param end
+     *            query end time
+     * @param isSelection
+     *            if the query is a selection
+     * @return the resulting query parameters
+     * @since 5.0
+     */
+    protected @NonNull Map<String, Object> getParameters(long start, long end, boolean isSelection) {
+        return FetchParametersUtils.timeQueryToMap(new TimeQueryFilter(Long.min(start, end), Long.max(start, end), 2));
+    }
+
+    /**
      * Algorithm to convert a model (List of {@link TmfTreeDataModel}) to the tree.
      *
      * @param start
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/linecharts/TmfCommonXAxisChartViewer.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/linecharts/TmfCommonXAxisChartViewer.java
index 00280ea..fd247c0 100644
--- a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/linecharts/TmfCommonXAxisChartViewer.java
+++ b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/linecharts/TmfCommonXAxisChartViewer.java
@@ -38,8 +38,10 @@
 import org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils.FlowScopeLog;
 import org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils.FlowScopeLogBuilder;
 import org.eclipse.tracecompass.internal.provisional.tmf.core.model.filters.TmfFilterAppliedSignal;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.internal.tmf.core.model.filters.TimeQueryRegexFilter;
 import org.eclipse.tracecompass.internal.tmf.ui.Activator;
+import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.IFilterProperty;
 import org.eclipse.tracecompass.tmf.core.model.xy.ISeriesModel;
@@ -208,12 +210,37 @@
      * @return An {@link TimeQueryFilter} instance that data provider will use to
      *         extract a model
      * @since 4.0
+     * @deprecated Use createQueryParameters instead
      */
+    @Deprecated
     protected @NonNull TimeQueryFilter createQueryFilter(long start, long end, int nb) {
         return new TimeQueryRegexFilter(getWindowStartTime(), getWindowEndTime(), nb, getRegexes());
     }
 
     /**
+     * Create map of parameters that will be used by updateData method. If a
+     * viewer need a more specialized map than just the time requested it's its
+     * responsibility to override this method and provide the desired instance.
+     *
+     * @param start
+     *            The starting value
+     * @param end
+     *            The ending value
+     * @param nb
+     *            The number of entries
+     * @return Map of parameters
+     * @since 5.0
+     */
+    protected @NonNull Map<String, Object> createQueryParameters(long start, long end, int nb) {
+        Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.timeQueryToMap(new TimeQueryFilter(start, end, nb));
+        Multimap<@NonNull Integer, @NonNull String> regexesMap = getRegexes();
+        if (!regexesMap.isEmpty()) {
+            parameters.put(DataProviderParameterUtils.REGEX_MAP_FILTERS_KEY, regexesMap.asMap());
+        }
+        return parameters;
+    }
+
+    /**
      * Gets the appearance of a given series. If appearance doesn't exist, a new one
      * will be created by the presentation provider
      *
@@ -303,8 +330,8 @@
                     if (numRequests == 0) {
                         return;
                     }
-                    TimeQueryFilter filter = createQueryFilter(getWindowStartTime(), getWindowEndTime(), numRequests);
-                    updateData(dataProvider, filter, fMonitor);
+                    Map<String, Object> parameters = createQueryParameters(getWindowStartTime(), getWindowEndTime(), numRequests);
+                    updateData(dataProvider, parameters, fMonitor);
                 } finally {
                     /*
                      * fDirty should have been incremented before creating the thread, so we
@@ -330,15 +357,15 @@
          *
          * @param dataProvider
          *                         A data provider
-         * @param filters
+         * @param parameters
          *                         A query filter
          * @param monitor
          *                         A monitor for canceling task
          */
-        private void updateData(@NonNull ITmfXYDataProvider dataProvider, @NonNull TimeQueryFilter filters, IProgressMonitor monitor) {
+        private void updateData(@NonNull ITmfXYDataProvider dataProvider, @NonNull Map<String, Object> parameters, IProgressMonitor monitor) {
             boolean isComplete = false;
             do {
-                TmfModelResponse<ITmfXyModel> response = dataProvider.fetchXY(filters, monitor);
+                TmfModelResponse<ITmfXyModel> response = dataProvider.fetchXY(parameters, monitor);
                 ITmfXyModel model = response.getModel();
                 if (model != null) {
                     updateDisplay(model, monitor);
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/linecharts/TmfFilteredXYChartViewer.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/linecharts/TmfFilteredXYChartViewer.java
index 75f0eb9..19a29ee 100644
--- a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/linecharts/TmfFilteredXYChartViewer.java
+++ b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/viewers/xycharts/linecharts/TmfFilteredXYChartViewer.java
@@ -11,12 +11,16 @@
 
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Map;
 
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.internal.tmf.core.model.filters.SelectionTimeQueryRegexFilter;
 import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderManager;
+import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
+import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.xy.ITmfTreeXYDataProvider;
 import org.eclipse.tracecompass.tmf.core.model.xy.ITmfXYDataProvider;
@@ -31,6 +35,7 @@
 import org.swtchart.Chart;
 
 import com.google.common.collect.Iterables;
+import com.google.common.collect.Multimap;
 import com.google.common.collect.Sets;
 
 /**
@@ -101,11 +106,22 @@
         super.traceClosed(signal);
     }
 
+    @Deprecated
     @Override
     protected TimeQueryFilter createQueryFilter(long start, long end, int nb) {
         return new SelectionTimeQueryRegexFilter(start, end, nb, fSelectedIds, getRegexes());
     }
 
+    @Override
+    protected @NonNull Map<String, Object> createQueryParameters(long start, long end, int nb) {
+        Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.selectionTimeQueryToMap(new SelectionTimeQueryFilter(start, end, nb, fSelectedIds));
+        Multimap<@NonNull Integer, @NonNull String> regexesMap = getRegexes();
+        if (!regexesMap.isEmpty()) {
+            parameters.put(DataProviderParameterUtils.REGEX_MAP_FILTERS_KEY, regexesMap.asMap());
+        }
+        return parameters;
+    }
+
     /**
      * Get the IDs of the selected entries
      *
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timegraph/BaseDataProviderTimeGraphView.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timegraph/BaseDataProviderTimeGraphView.java
index 88f0e09..573a420 100644
--- a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timegraph/BaseDataProviderTimeGraphView.java
+++ b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timegraph/BaseDataProviderTimeGraphView.java
@@ -19,10 +19,12 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.SubMonitor;
 import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.tracecompass.internal.tmf.core.model.filters.TimeGraphStateQueryFilter;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
 import org.eclipse.tracecompass.internal.tmf.ui.Activator;
 import org.eclipse.tracecompass.statesystem.core.StateSystemUtils;
 import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderManager;
+import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
+import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.IFilterProperty;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphArrow;
@@ -30,7 +32,9 @@
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphRowModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphState;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphEntryModel;
+import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphModel;
 import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphState;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
 import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
 import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
@@ -115,7 +119,7 @@
         }
         boolean complete = false;
         while (!complete && !monitor.isCanceled()) {
-            TmfModelResponse<List<TimeGraphEntryModel>> response = dataProvider.fetchTree(new TimeQueryFilter(0, Long.MAX_VALUE, 2), monitor);
+            TmfModelResponse<TmfTreeModel<@NonNull TimeGraphEntryModel>> response = dataProvider.fetchTree(FetchParametersUtils.timeQueryToMap(new TimeQueryFilter(0, Long.MAX_VALUE, 2)), monitor);
             if (response.getStatus() == ITmfResponse.Status.FAILED) {
                 Activator.getDefault().logError(getClass().getSimpleName() + " Data Provider failed: " + response.getStatusMessage()); //$NON-NLS-1$
                 return;
@@ -124,10 +128,10 @@
             }
             complete = response.getStatus() == ITmfResponse.Status.COMPLETED;
 
-            List<TimeGraphEntryModel> model = response.getModel();
+            TmfTreeModel<@NonNull TimeGraphEntryModel> model = response.getModel();
             if (model != null) {
                 synchronized (fEntries) {
-                    for (TimeGraphEntryModel entry : model) {
+                    for (TimeGraphEntryModel entry : model.getEntries()) {
                         TimeGraphEntry uiEntry = fEntries.get(dataProvider, entry.getId());
                         if (entry.getParentId() != -1) {
                             if (uiEntry == null) {
@@ -286,12 +290,17 @@
 
         for (Entry<ITimeGraphDataProvider<? extends TimeGraphEntryModel>, Collection<Long>> entry : providersToModelIds.asMap().entrySet()) {
             ITimeGraphDataProvider<? extends TimeGraphEntryModel> dataProvider = entry.getKey();
-            TimeGraphStateQueryFilter filter = new TimeGraphStateQueryFilter(times, entry.getValue(), getRegexes());
-            TmfModelResponse<List<ITimeGraphRowModel>> response = dataProvider.fetchRowModel(filter, monitor);
+            SelectionTimeQueryFilter filter = new SelectionTimeQueryFilter(times, entry.getValue());
+            Map<@NonNull String, @NonNull Object> parameters = FetchParametersUtils.selectionTimeQueryToMap(filter);
+            Multimap<@NonNull Integer, @NonNull String> regexesMap = getRegexes();
+            if (!regexesMap.isEmpty()) {
+                parameters.put(DataProviderParameterUtils.REGEX_MAP_FILTERS_KEY, regexesMap.asMap());
+            }
+            TmfModelResponse<TimeGraphModel> response = dataProvider.fetchRowModel(parameters, monitor);
 
-            List<ITimeGraphRowModel> model = response.getModel();
+            TimeGraphModel model = response.getModel();
             if (model != null) {
-                zoomEntries(fEntries.row(dataProvider), model, response.getStatus() == ITmfResponse.Status.COMPLETED, sampling);
+                zoomEntries(fEntries.row(dataProvider), model.getRows(), response.getStatus() == ITmfResponse.Status.COMPLETED, sampling);
             }
             subMonitor.worked(1);
         }
@@ -416,7 +425,7 @@
 
         for (TraceEntry entry : Iterables.filter(traceEntries, TraceEntry.class)) {
             ITimeGraphDataProvider<? extends TimeGraphEntryModel> provider = entry.getProvider();
-            TmfModelResponse<List<ITimeGraphArrow>> response = provider.fetchArrows(queryFilter, monitor);
+            TmfModelResponse<List<ITimeGraphArrow>> response = provider.fetchArrows(FetchParametersUtils.timeQueryToMap(queryFilter), monitor);
             List<ITimeGraphArrow> model = response.getModel();
 
             if (model != null) {
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/TimeGraphEntry.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/TimeGraphEntry.java
index 59d2e69..45a49e2 100644
--- a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/TimeGraphEntry.java
+++ b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/TimeGraphEntry.java
@@ -158,7 +158,7 @@
      *            The end time of this entry
      */
     public TimeGraphEntry(String name, long startTime, long endTime) {
-        fModel = new TimeGraphEntryModel(-1, -1, name, startTime, endTime);
+        fModel = new TimeGraphEntryModel(-1, -1, Collections.singletonList(name), startTime, endTime);
     }
 
     /**
@@ -229,7 +229,7 @@
          * Model is immutable, this is the only way to do this, consider not updating
          * name in the future?
          */
-        fModel = new TimeGraphEntryModel(fModel.getId(), fModel.getParentId(), name, getStartTime(), getEndTime(), fModel.hasRowModel());
+        fModel = new TimeGraphEntryModel(fModel.getId(), fModel.getParentId(), Collections.singletonList(name), getStartTime(), getEndTime(), fModel.hasRowModel());
     }
 
     @Override
@@ -435,7 +435,7 @@
          * Model is immutable, this is the only way to do this, consider not updating
          * bounds in the future?
          */
-        fModel = new TimeGraphEntryModel(fModel.getId(), fModel.getParentId(), getName(), newStart, newEnd, fModel.hasRowModel());
+        fModel = new TimeGraphEntryModel(fModel.getId(), fModel.getParentId(), Collections.singletonList(getName()), newStart, newEnd, fModel.hasRowModel());
     }
 
     /**
@@ -523,7 +523,7 @@
 
     @Override
     public String toString() {
-        return getClass().getSimpleName() + '(' + fModel.getName() + ')';
+        return getClass().getSimpleName() + '(' + fModel.getLabels() + ')';
     }
 
     /**