diff --git a/dev-doc/API_policy.md b/dev-doc/API_policy.md
new file mode 100644
index 00000000..9edcff16
--- /dev/null
+++ b/dev-doc/API_policy.md
@@ -0,0 +1,38 @@
+# Memory Analyzer API Policy
+
+This document provides the current API Policy for Memory Analyzer.
+
+## Purpose
+
+Eclipse MAT is built on top of the Eclipse IDE framework, and the components can
+be embedded inside other deployments. As an OSGI framework-capable runtime,
+the components export known consistent APIs that allow other developers and
+components to work together within the IDE.
+
+For example, the [Eclipse MAT Calcite Plugin](https://github.com/vlsi/mat-calcite-plugin)
+plugs directly into the Eclipse IDE and interacts with the Eclipse MAT
+components to enhance its functionality.
+
+## Declared API
+
+The declared APIs in Memory Analyzer are provided as public and documented. The
+API compatibility between different versions of Memory Analyzer should be
+reflected by the version numbers, following the [Eclipse versioning policy](https://github.com/eclipse-platform/eclipse.platform/blob/master/docs/VersionNumbering.md).
+
+## Some examples
+
+- Changes to the API - adding new APIs or deprecating APIs should be documented
+and communicated to the community (e.g. via GH issue and/or mailing list).
+
+- Deprecated API should be available for at lease one major release.
+
+## Provisional and internal API
+
+Provisional APIs should be used while development is occurring. If successfully
+adopted, they might become declared APIs. If not, they can be removed. In any
+situation, the community should be notified.
+
+## Tooling
+
+See the [Contributor Reference](Contributor_Reference.md) for some notes on API
+tooling and configuration.
diff --git a/dev-doc/Extending_Memory_Analyzer.md b/dev-doc/Extending_Memory_Analyzer.md
new file mode 100644
index 00000000..4d774441
--- /dev/null
+++ b/dev-doc/Extending_Memory_Analyzer.md
@@ -0,0 +1,558 @@
+# Extending Memory Analyzer
+
+## Introduction
+
+The Memory Analyzer tool offers several possibilities to extend it. This page
+contains an overview of the different extension points and what can be achieved
+with them.
+
+Within the extensions one will usually extract certain pieces of information
+from the objects in the heap dump. See [Reading data from heap dumps](Reading_data_from_heap_dumps.md)
+for more details on how to read data from a heap dump.
+
+## Setting up a development environment for writing extensions
+
+It is not necessary to download the source of Memory Analyzer to be able to
+write extensions. A recent binary version is sufficient.
+
+### Development environment
+
+1. Have a copy of an Eclipse Java Development environment installed
+2. Download and install latest copy of Memory Analyzer
+
+### Target platform setup
+
+Create MAT as a target platform:
+1. Windows->Preferences->Plug-in Development->Target Platform
+2. Add->Nothing->Next
+3. Name: MAT
+4. Locations->Add->Installation
+5. Location: path_to_MAT/mat
+6. Finish
+7. Select MAT as active target platform
+
+## Creating a plug-in project
+
+1. File->New->Other->Plug-in project
+2. Name: MAT Extension
+3. ->Next
+4. Execution Environment: (pick current Java generation)
+5. No activator (unless you are doing something complicated)
+6. No UI contribution
+7. No API analysis
+8. No template
+9. ->Finish
+
+### Configure depedencies
+
+1. add `org.eclipse.mat.api` (to allow use of the API)
+2. Save (cntl-S)
+
+### Configure extensions
+
+1. select `org.eclipse.mat.api.nameResolver` (to integrate with extensions)
+2. ->Finish
+3. click on impl
+4. Adjust package name and class name to suit
+5. ->Finish
+6. Add before the class definition an annotation,
+
+ ```java
+ @Subject("java.lang.Runtime")
+ ```
+
+7. Organize imports (cntl-shift-O)
+8. Edit the code to perform the required function. For example
+
+ ```java
+ public String resolve(IObject object) {
+ // return null;
+ return "The Java runtime of size " + object.getUsedHeapSize();
+ }
+ ```
+
+9. Save
+
+Tip - If using Eclipse, note the javadoc help for `IObject`,
+`IClassSpecificNameResolver`. Note the method list for object.
+
+### To test
+
+Select Plug-in, Run As->Eclipse Application.
+
+### To package
+
+1. File->Export->Plug-in Development->Deployable plug-ins and fragments
+2. ->next
+3. select plug-in
+4. Destination: Directory: path_to_MAT/mat
+5. ->Finish
+
+## The Name Resolver Extension
+
+The name resolver extension point provides a mechanism to give a readable
+description of an object, similar to what a `toString()` method will do. Some
+extensions which MAT provides are to show the content of objects representing
+String, to show the bundle symbolic name for Equinox classloaders, to show the
+thread name for Thread objects, etc. You can create and contribute your own
+resolvers.
+
+The extension should implement the `IClassSpecificNameResolver` interface which
+defines a single method.
+
+```java
+public String resolve(IObject object) throws SnapshotException;
+```
+
+The method takes an `IObject` as an argument and should return a string
+representation.
+
+To specify the class for which the resolver should be used one can use the
+annotation `@Subject`.
+
+```java
+@Subject("x.y.z.MyClass")
+public class MyClassResolver implements IClassSpecificNameResolver {
+ public String resolve(IObject obj) throws SnapshotException {
+ // implementation
+ }
+}
+```
+
+The method `getClassSpecificName()` of `IObject` will look for extensions which
+match the class of the object and execute the `resolve()` method to return the
+resolved String. Thus it is relatively easy to return a description based on one
+or more String fields, as strings are already resolved.
+
+Here is a sample implementation that will return the name of an Eclipse Job:
+
+```java
+@Subject("org.eclipse.core.runtime.jobs.Job")
+public class JobNameResolver implements IClassSpecificNameResolver
+{
+ @Override
+ public String resolve(IObject object) throws SnapshotException
+ {
+ IObject name = (IObject) object.resolveValue("name");
+ if (name != null) return name.getClassSpecificName();
+ return null;
+ }
+}
+```
+
+## Queries in Memory Analyzer
+
+### Introduction to Queries
+
+Most of the functionality in Memory Analyzer which is exposed to the user of the
+tool is provided via queries implementing the `IQuery` interface, for example
+"Histogram", "Retained Set", etc.
+
+Queries extract and process data from the heap dump using the MAT API, and
+provide the result to the user in the form of a table, a tree, free text, etc.
+Queries show up in the "Queries" menu of the tool, and often in the context
+menus on objects.
+
+An important feature of the queries is that they can "collaborate", i.e. the
+user can use (part of) the result of one query and pass it as input parameters
+to another query.
+
+An example of such "cooperation" - you select "Histogram" to show a class
+histogram of all objects, then choose say `java.util.HashMap`. From the context
+menu call "Retained Set". The retained set is using as input the results of the
+histogram selection. You can then select a line in this retained set and pass
+the corresponding objects to yet another query.
+
+### The `IQuery` Interface
+
+To implement a query one needs to implement the `IQuery` interface. The
+implementation should provide a (default) constructor without parameters.
+
+The IQuery interface defines just one method:
+
+```java
+public IResult execute(IProgressListener listener) throws Exception;
+```
+
+As a parameter one gets only a progress listener `IProgressListener` to report
+progress. All other input that a query needs is deaclared with annotations on
+the fields of the query and injected from Memory Analyzer at runtime. The
+fields used for arguments injection should be declared public.
+
+For more details on getting input, see the Passing Arguments section (below).
+
+The return type of the execute method is `IResult`, which is a marker interface.
+The different result types are described in the section Query Results (below).
+
+### Query Scope
+
+Queries are stateless. Every time the user executes a query a new instance of
+the `IQuery` implementation is created. The required input is injected into the
+fields of the instance and the execute method is called.
+
+### Describing the Query with Annotations
+
+When you write a query it will appear in the context menus, and Memory Analyzer
+will open an Arguments Wizard for specifying the required arguments. The wizard
+will also show some help for the query and its arguments.
+
+The metadata - how a query will be named, under which category (sub-menu) it
+will appear, the help text, etc are all provided by annotating the query.
+
+The following meta-data related annotations are available and should be at the
+`Class` level for the query.
+
+| Annotation | Description |
+|------------|-------------|
+| @CommandName | used for command line and query browser |
+| @Name | the visible name on the menu, `nn\|` to set order |
+| @Category | the menu section (sub-menu), `/` to cascade, `nn\|` to set order |
+| @Help | explanation of query |
+| @HelpUrl | link into the help system |
+| @Icon | icon for the query (shown in the menu) |
+| @Usage | example usage – defaults to command name + args |
+
+The values can also be externalized. To do so, put them into an
+`annotations.properties` file in the package directory.
+
+#### Example annotations
+
+```java
+@Category("Sample Queries")
+@Name("List Jobs Query")
+@Help("This is a sample query, which lists all jobs with a given name")
+public class SampleQuery implements IQuery {
+ ...
+}
+```
+
+To externalize these values, `annotations.properties` will look something like:
+
+```properties
+SampleQuery.category = Sample Queries
+SampleQuery.name = List Jobs Query
+SampleQuery.help = This is a sample query, which lists all jobs with a given name
+```
+
+### Passing Arguments to a Query
+
+A nice property of queries is that they can interact with each other. In other
+words, parts of the result from one query (say one line in a histogram) can be
+passed to a different query using the context menus.
+
+To support this queries need to declare what kind of arguments they require and
+delegate to the Memory Analyzer to collect this information. Memory Analyzer
+will inject it into the queries before executing them. If needed, Memory
+Analyzer does this by opening the Arguments Wizard.
+
+To declare an input parameter a query has to define a public field and annotate
+it with the `@Argument` annotation. To provide a help message specific on the
+concrete argument, add also the `@Help` annotation to the public field.
+
+The following types are currently supported as arguments:
+
+| Argument type | Description |
+|---------------|-------------|
+| `ISnapshot` | the snapshot corresponding to the currently open editor |
+| `IHeapObjectArgument` | good way of getting objects |
+| `String`, `Pattern`, `int`, `boolean`, `float`, `double` | supplied directly via wizard or command line |
+| `IContextObject` | row with one object |
+| `IContextObjectSet` | row with multiple objects or OQL query to return those objects |
+| `IQueryContext` | a more general way of extracting information about the snapshot which is not tied to the snapshot API |
+| arrays or lists of the above | for multiple items |
+| enums | can be used to provide a fixed choice list |
+| `File` | for input or output files |
+
+### Comparison Queries
+
+Comparison queries are run from the Compare Basket but are invoked in a similar
+way. Each row of the Compare Basket is a whole result of a previous query;
+either a tree or table.
+
+Queries with arguments suitable for a comparison operation are only offered in
+the Compare Menu and not from the editor pane. Comparison arguments are as
+follows, all arguments should be a `List` or `[]` array of:
+
+| Compare Argument | Description |
+|------------------|-------------|
+| `IResultTable` | for comparison queries only operating on tables |
+| `IResultTree` | for comparison queries only operating on trees |
+| `IStructuredResult` | for comparison queries operating on tables and trees |
+| `RefinedTable` | for comparison queries only operating on tables, uses the filtered and sorted version of the previous result with any derived columns like retained size |
+| `RefinedTree` | for comparison queries only operating on tables, uses the filtered and sorted version of the previous result with any derived columns like retained size |
+| `RefinedStructuredResult` | for comparison queries operating on tables and trees, uses the filtered and sorted version of the previous result with any derived columns like retained size |
+| `ISnapshot` | the snapshots corresponding to the tables / trees, in the same order |
+
+Consider using `RefinedStructuredResult` for your comparison queries as the query may then be more flexible for the end user.
+
+Some standard arguments are also available to comparison queries:
+
+| Argument type | Description |
+|---------------|-------------|
+| `String`, `Pattern`, `int`, `boolean`, `float`, `double` | supplied directly via wizard or command line |
+| enums | can be used to provide a fixed choice list |
+| `File` | for input or output files |
+
+### Qualifications on Query Arguments
+
+Parameters on the `@Argument` annotation can be used to specify some further
+restrictions and hints to be followed by the wizard and during injection.
+
+```java
+@Argument
+public ISnapshot snapshot;
+
+@Argument(advice = Advice.HEAP_OBJECT, isMandatory = false, flag = Argument.UNFLAGGED)
+public int[] objects;
+
+@Argument(isMandatory = false, flag = "t")
+public int thresholdPercent = 1;
+```
+
+| Annotation parameter | Description |
+|----------------------|-------------|
+| isMandatory | a boolean parameter to tell MAT if it can execute the query without the argument |
+| flag | a String used instead of the field name to identify the argument in the command line and in the query browser |
+| Advice | qualifies the way data is inserted into the field (see below) |
+
+Advice arguments can be found in `org.eclipse.mat.query.annotations.Argument` as
+the `Advice` enum.
+
+| Advice argument | Description |
+|-----------------|-------------|
+| Advice.HEAP_OBJECT | the int or Integer is an object id, not a number |
+| Advice.SECONDARY_SNAPSHOT | the snapshot is another snapshot, which should be prompted for, not the current one |
+| Advice.CLASS_NAME_PATTERN | the pattern will be used to match class names |
+| Advice.DIRECTORY | the file parameter is meant to be a directory |
+| Advice.SAVE | the file parameter is meant to be used to save data |
+
+#### Reading data from supplied arguments
+
+See [Reading data from heap dumps](Reading_data_from_heap_dumps.md) for how to
+extract data from supplied arguments, including use of `ISnapshot`, `IObject`
+and the use of object IDs.
+
+### Calling One Query from Another
+
+Supplied queries are not a Memory Analyzer API, so user written queries should
+not link to them directly. It is possible to call them by name, though the query
+names and arguments can vary from release to release.
+
+```java
+String query = "SELECT s, toString(s) from java.lang.String s";
+IResult ir = SnapshotQuery.lookup("oql", snapshot).setArgument("queryString", query).execute(listener);
+```
+
+An enum argument may need to be set using a parsed string, as calling via
+`setArgument` often doesn't work as the enum type is inaccessible.
+
+```java
+SnapshotQuery query = SnapshotQuery.parse("dominator_tree -groupby BY_CLASSLOADER", snapshot);
+IResultTree t = (IResultTree)query.execute(new VoidProgressListener());
+```
+
+### Query Results
+
+- `TextResult` - A simple result that renders its input as text.
+- `IStructuredResult` - A way of display data about lots of objects
+ - `IResultTable` - A table of objects
+ - `Histogram` - A table of objects where each row is all the objects of
+ one class
+ - `ListResult` - A way of displaying a Java List of things, where the
+ fields from each thing are also given
+ - `PropertyResult` - A way of displaying details about one object based
+ on a list of attributes
+ - `IResultTree` - A tree of objects
+- `IResultPie` - A pie chart
+- `QuerySpec` - A good way of displaying the results of executing another query
+
+## Reports in Memory Analyzer
+
+Several queries can be combined into a report which could then be run from the
+Run Report... menu option or in batch mode.
+
+### Report definition
+
+The report definition is written in XML and can be validated using the schema
+held in `org.eclipse.mat.report/schema/report.xsd`. The result of running a
+report will be an HTML page or a CSV data file. Queries can be run using the
+`query` element, using the command `element` to specify which command should be
+run.
+
+Other reports can be run using the `template` element. The `section` element can
+be used to combine multiple `query`, `template` and `section` elements and is
+displayed in a report as a collapsible part or a separate file.
+
+Two examples show how the report definition is written. `overview.xml` has a
+section and `suspects.xml` also has a `template` element referencing another
+report to be run and included. They are available in `plugins/org.eclipse.mat.api/META-INF/reports/`.
+
+The `param` element allows output to be controlled:
+
+- The params can be used to control generation of tables - as HTML or CSV files,
+to limit or increase the number of lines displayed, and to omit, sort or filter
+columns.
+- Some params just control the current section - some also control any inner
+sections unless overridden.
+- A param can also be used elsewhere in the report as `${param_name}` - in the
+command name and other param values.
+- Values are documented in `org.eclipse.mat.report.Params` interface as well as
+in the `Params.Html` and `Params.Rendering` javadoc.
+- Parameters can be passed to a report definition using `ParseHeapDump`
+- A param value given on the command line will override a value given in a
+report definition.
+
+```bash
+ParseHeapDump myheapdump.hprof -myparam=myparam_value myreport.xml
+```
+
+The report definition can be tested as Run Expert System Test > Run Report.
+
+### Report definition extension point
+
+If a report definition is incorporated into a plug-in then the report definition
+extension point should be used. Then when the new plug-in is installed into MAT
+the report will be available to run from the Memory Analyzer GUI.
+
+Values in the report definition can then be externalized using a definition in
+the `plugin.properties` file and referred to by `%myval Default value`.
+
+### Executing a Report in Unattended Mode
+
+Once you create a Report extension you can find it next to other reports like
+the "Leak Suspects" in the Memory Analyzer GUI. Besides this, one can execute
+reports in an unattended mode by running the "org.eclipse.mat.api.parse"
+application.
+
+Here is an example how to setup a Run Configuration to execute the report
+"my_repory" located in the plugin "my_report_plugin":
+
+- Run As -> Run Configurations
+- Set "Run An Application" to "org.eclipse.mat.api.parse"
+- Set the Program arguments to
+```bash
+${file_prompt} my_report_plugin:my_report
+```
+
+When you run this you will get a popup to select a heap dump file. It will be
+then parsed and the report will be executed for it. The result however is not
+open in the IDE, it is saved in the file system next to the dump.
+
+#### Parameters
+
+You can also define options on the command line. This can be as
+
+```bash
+${file_prompt} "-my_parm=my special value" my_report_plugin:my_report
+```
+and then access the variable inside the report XML as
+
+```xml
+
+
+
+ my_query -myopt "${my_parm}"
+
+
+```
+
+## Request Resolvers
+
+A request resolver is a piece of coding which is capable of extracting details
+about what a thread was doing, using the information from the thread object and
+its java local objects. The information provided by a request resolver is
+included in the Leak Suspects report.
+
+When is this useful? There are often OutOfMemoryErrors which are not caused by a
+memory leak, but rather by some "greedy" operation - an attempt to load a huge
+file fully into memory, an attempt to build scan a whole DB table and keep the
+results in memory, etc... In such cases the Leak Suspect report will often point
+to the thread as the suspect object, because its local objects (objects on the
+thread's stack) are eating too much memory. In such cases it is very helpful to
+know what the thread was doing and to get some insights on this activity.
+
+Examples:
+
+- tell that a thread was processing an HTTP request and extract the concrete request and some parameters
+- show an SQL statement that has been processed when an OOM error occured
+- display the name of the Eclipse Job which has been processed
+- etc...
+
+### The `IRequestDetailsResolver` Interface
+
+To implement a request resolver one needs to implement the
+`IRequestDetailsResolver` interface. To specify for which type of local objects
+this request resolver can provide information, use the the `@Subject` annotation
+on the implementation class.
+
+The interface defines just one method:
+
+```java
+void complement(ISnapshot snapshot, IThreadInfo thread, int[] javaLocals, int thisJavaLocal,
+ IProgressListener listener) throws SnapshotException;
+```
+
+The complement method will be called by Memory Analyzer whenever it collects
+information for a thread and the thread has a local object (somewhere on the
+stack) which matches the type specified by `@Subject`. As parameters one will
+receive all necessary context information to extract the needed information:
+
+| parameters | description |
+|------------|-------------|
+| snapshot | the whole dump |
+| thread | a IThreadInfo object representing the thread being analyzed |
+| javaLocals | all the local variables, as object IDs |
+| thisJavaLocal | the object ID of the local object matching the `@Subject` |
+
+Within the `complement()` method one should extract helpful information about
+the activity of the thread and add it to the `IThreadInfo` object using the
+`addRequest()` method. The `addRequest()` method takes two parameters - a
+String with short description appearing on the first page of the Leak Suspects
+report, and an IResult with more details about the request (could be a table
+with all properties, etc...).
+
+Here is a code sample for a request resolver:
+
+```java
+/* Specify that I can extract information from ProgressManager$JobMonitor objects */
+@Subject("org.eclipse.ui.internal.progress.ProgressManager$JobMonitor")
+public class JobRequestResolver implements IRequestDetailsResolver {
+
+ @Override
+ public void complement(ISnapshot snapshot, IThreadInfo thread,
+ int[] javaLocals, int thisJavaLocal, IProgressListener listener)
+ throws SnapshotException {
+ IObject monitor = snapshot.getObject(thisJavaLocal); // get the IOjbect for the JobMonitor
+ IObject job = (IObject) monitor.resolveValue("job"); // get the value of the job field
+ String jobName = job.getClassSpecificName(); // get the symbolic represenation of the job
+
+ String summary = "This thread executes the job [" + jobName + "]";
+ IResult sampleDetails = new TextResult("Job object is = [" + job.getDisplayName() + "]");
+
+ thread.addRequest(summary, sampleDetails); // add the request information
+ thread.addKeyword(jobName); // add the job name to the keywords
+ }
+}
+```
+
+This sample request resolver will add to the leak suspect report a line like:
+
+```
+This thread executes the job [Sample greedy job]
+```
+
+if the thread was processing an Eclipse job. It will add as details the object
+instance of the Job implementation.
+
+## Adding a New Heap Dump Format
+
+Memory Analyzer can also be extended to support more heap dump formats. A
+detailed description how to do this can be found in the page
+[Adding a new heapdump format](Adding_a_new_heapdump_format.md).
+
+## Contributing back to the project
+
+If your extension to Memory Analyzer would be useful to other people, please
+consider contributing it back to the project.
diff --git a/dev-doc/Index_files.md b/dev-doc/Index_files.md
new file mode 100644
index 00000000..1901823d
--- /dev/null
+++ b/dev-doc/Index_files.md
@@ -0,0 +1,63 @@
+# Index files
+
+Memory Analyzer uses several indexes to enable access to different parts of the
+snapshot.
+
+| Index name | description |
+|------------|-------------|
+| IDENTIFIER | IntToLong object ID to object address |
+| O2CLASS | object ID to class ID |
+| A2SIZE | array object ID (or other non-fixed size object) to encoded size (32-bits) |
+| INBOUND | object ID to list of object IDs |
+| OUTBOUND | object ID to list of object IDs |
+| DOMINATED | Dominated: object id to N dominated object ids |
+| O2RETAINED | object ID to long |
+| DOMINATOR | Dominator of: object id to the id of its dominator |
+| I2RETAINED | cache of size of class, classloader (read/write) |
+
+## IntIndexReader
+
+For an index file like O2CLASS, the file is stored as many `ArrayIntCompressed`
+followed by an index: `IntIndexReader`. There is a special adjustment to cope
+with >2^31 entries files as that can be needed for 1 to N files.
+
+On reading there is a `SoftReference` cache of those `ArrayIntCompressed` pages.
+
+The data is read using a `SimpleBufferedRandomAccessInputStream` which just has
+local buffer.
+
+## LongIndexReader
+
+LongIndexReader is similar (without the adjustment for 2^31 entries).
+
+## PositionIndexReader
+
+PositionIndexReader is similar (without the adjustment for 2^31 entries).
+
+## 1 to N reader
+
+`IntIndex1NReader` has two parts: a body and an header, and a final `long` of
+the position of the split in the file.
+
+For an input, use the header to find the position of the start in the body and
+the header via (index+1) to find the position of the next entry.
+Read data between the two from the body.
+
+## Random Access File caching
+
+HPROF random access to GZIP compressed files to read fields and array contents
+
+- `org.eclipse.mat.hprof.DefaultPositionInputStream`
+ - `org.eclipse.mat.parser.io.BufferedRandomAccessInputStream`
+ - `HashMapLongObject`
+ - `[*N] page`
+ - `[*N] SoftReference`
+ - `buffer byte[512]`
+ - `org.eclipse.mat.hprof.CompressedRandomAccessFile`
+ - `org.eclipse.mat.hprof.SeekableStream`
+ - `[*N} org.eclipse.mat.hprof.SeekableStream$PosStream`
+ - `SoftReference`
+ - `org.eclipse.mat.hprof.GZIPInputStream2`
+ - `io.nayuki.deflate.InflaterInputStream`
+ - `inputBuffer byte[16384]`
+ - `dictionary byte[32768]`
diff --git a/dev-doc/MAT_capabilities.md b/dev-doc/MAT_capabilities.md
new file mode 100644
index 00000000..3416e194
--- /dev/null
+++ b/dev-doc/MAT_capabilities.md
@@ -0,0 +1,38 @@
+NOTE this page is here for archival purposes only.
+
+# MAT Capabilities
+
+This document provides some sample [capability definitions](https://wiki.eclipse.org/Eclipse/Capabilities)
+for the Memory Analyzer (MAT). It describes:
+
+1. Where to find the existing Capabilities plug-in in SVN
+2. Or how to implement your own Capabilities for Memory Analyzer
+
+## Existing Capabilities Plug-in
+
+The plug-in `org.eclipse.mat.ui.capabilities` contains Capabilities definition
+for Memory Analyzer.
+
+The plug-in can be found in the project repo at:
+
+`plugins/org.eclipse.mat.ui.capabilities`
+
+[Link](https://github.com/eclipse-mat/mat/tree/master/plugins/org.eclipse.mat.ui.capabilities)
+
+## Capabilities Implementation
+
+The code snippet below shows how to turn off Memory Analyzer functionality in
+the workbench via Capabilities:
+
+```xml
+
+
+
+
+
+```
diff --git a/dev-doc/Reading_data_from_heap_dumps.md b/dev-doc/Reading_data_from_heap_dumps.md
new file mode 100644
index 00000000..622c651f
--- /dev/null
+++ b/dev-doc/Reading_data_from_heap_dumps.md
@@ -0,0 +1,246 @@
+# Reading data from heap dumps (programmatically)
+
+The Memory Analyzer offers an API which one can use to open a heap dump and
+inspect its contents programmatically. This API is used by the MAT tool itself
+to offer the different end-user features available in the tool. An overview of
+this API is available on this page.
+
+## The ISnapshot interface
+
+The most important interface one can use to extract data from a heap dump is
+`ISnapshot`. `ISnapshot` represents a heap dump and offers various methods for
+reading object and classes from it, getting the size of objects, etc...
+
+To obtain an instance of `ISnapshot` one can use static methods on the
+`SnapshotFactory` class. However, this is only needed if the API is used to
+implement a tool independent of Memory Analyzer.
+
+If you are writing extensions to MAT, you typically will receive a reference to
+an already opened heap dump either by injection or as a method parameter. See
+[Extending Memory Analyzer](Extending_Memory_Analyzer.md).
+
+### Opening a snapshot using `SnapshotFactory`
+
+To open an existing heap dump in one of the supported formats call the
+`SnapshotFactory.openSnapshot()` method.
+
+```java
+public static ISnapshot openSnapshot(File file, IProgressListener listener) throws SnapshotException
+```
+
+As parameters pass the heap dump file and a valid progress listener (see below).
+
+When you are finished with using the `ISnapshot` instance call the
+`SnapshotFactory.dispose(ISnapshot)` method to free the resources and unlock any
+used files.
+
+### The `IProgressListener` interface
+
+The `IProgressListener` listener interface offers (as the name suggests)
+functionality to report the progress of different computations.
+
+Usually if you are extending the tool then MAT will pass an instance of an
+object implementing the interface to you.
+
+In case you are opening the heap dump on your own, you may need to create the
+listener on your own. The tool provides some helper classes:
+
+| Listener class | Description |
+|----------------|-------------|
+| `ConsoleProgressListener` | Logs progress to Java stdout/console. |
+| `VoidProgressListener` | Ignores progress. |
+| `ProgressMonitorWrapper` | Can wrap the `org.eclipse.core.runtime.IProgressMonitor`. |
+| `SimpleMonitor` | Can be used to generate several `IProgressListener` objects each handling a proportion of work from a supplied `IProgressListener`. |
+
+## The object model
+
+The following hierarchy of interfaces represents the object model that MAT
+builds for objects in the heap.
+
+They can all be found in `org.eclipse.mat.snapshot.model.*` package.
+
+- `IObject` representing any object on the heap.
+ - `IClass` represents a `java.lang.Class`.
+ - `IInstance` represents an ordinary Java object instance.
+ - `IClassLoader` represents a classloader.
+ - `IArray` represents an array.
+ - `IObjectArray` represents an object array.
+ - `IPrimitiveArray` represents a primitive array.
+
+This model is pretty straightforward and easy to understand. However, there is
+one major challenge – the memory needed to maintain such a model. As often there
+are millions of objects in a heap dump, MAT is not keeping such a model through
+the lifetime of an ISnapshot. Instead it gives every object an id (starting from
+0 and growing by one) and uses these ids to obtain information about objects
+(like its class, size, referenced objects, etc) from the `ISnapshot` instance.
+
+Also most of the heavy computations traversing potentially millions of objects
+(e.g. calculating a retained size, computing paths, etc) are done without using
+the object model described above. The use of the classes described here is
+needed (and recommended) only when the full information about an object is
+needed – including its field names and their (possibly primitive) values.
+
+## Single objects, objects id and address
+
+To get an object by its id use the method `getObject(int id)` of `ISnapshot`.
+
+Objects have also addresses (usually visualized as hexadecimal number next to
+the object). One can map between object ids and addresses using the following
+two methods of `ISnapshot`:
+
+```java
+ public long mapIdToAddress(int objectId) throws SnapshotException;
+ public int mapAddressToId(long objectAddress) throws SnapshotException;
+```
+
+If you already have an instance of `IObject` you can call `getObjectId()` and
+`getObjectAddress()` directly.
+
+## Getting classes
+
+The `ISnapshot` interface offers the possibility to get a class by its fully
+qualified name or get a collection of classes using a regex pattern.
+
+```java
+ public Collection getClassesByName(String name, boolean includeSubClasses) throws SnapshotException;
+ public Collection getClassesByName(Pattern namePattern, boolean includeSubClasses) throws SnapshotException;
+```
+
+Both methods return a collection of classes, as classes with the same name but
+loaded with different class loaders are treated as separate classes. To get a
+collection of all classes available in the heap dump, just call the
+`getClasses()` method without any parameters
+
+## Get all instances of a class
+
+To get all instances of a certain class first obtain the class (or collection
+of classes) and then call the `getObjectIds` method on the `IClass` instance:
+
+```java
+ public int[] getObjectIds() throws SnapshotException;
+```
+
+The returned `int[]` contains the ids of all objects of the class.
+
+## Inspecting referenced objects
+
+There are various possibilities to explore the outgoing references of an object.
+The most performant way is to use the `getOutboundReferentIds(int)` methods of
+`ISnapshot`.
+
+```java
+ public int[] getOutboundReferentIds(int objectId) throws SnapshotException;
+```
+
+This method takes an object id and returns an array containing all the ids of
+all referenced objects. The reference objects include also object referenced by
+artificially modeled references. This method gives a fast way to traverse the
+object graph.
+
+The `IObject` interface also provides several ways to explore its references:
+
+```java
+ public List getOutboundReferences();
+```
+
+A `NamedReference` allows you to look at the name of the reference, get the id
+and the address of the referenced object, and also get the referenced object as
+`IObject`.
+
+If you are looking for the value of a specific field or reference, then the most
+convenient way to achieve it is to use the `resolveValue` method.
+
+```java
+ public Object resolveValue(String field) throws SnapshotException;
+```
+
+It takes as an argument a dot-separated path to the field of interest. This
+means that one can access not only the fields of the object itself, but to
+provide a path through some of the references. Here is an example:
+
+```java
+IObject myObject = snapshot.getObject(objectId);
+IObject fName = myObject.resolveValue(“department.customer.firstName”);
+```
+
+This code will go through the fields of myObject and will search for a field
+named "department". If department itself is not a primitive MAT will find its
+field "customer", and then find the field "firstName" in the object referenced
+through "customer".
+
+If the field is of primitive type, then `resolveValue()` will return the
+corresponding boxed class, allowing you to read these directly:
+
+```java
+IObject hashMap = … ; // some IObject representing a HashMap
+int size = hashMap.resolveValue(“size”);
+```
+
+## Printing objects
+
+The IObject interface defines several methods for getting a String
+representation of the object.
+
+| Method | Description |
+|--------|-------------|
+| `getTechnicalName()` | returns a string in the format ` @ `. |
+| `getClassSpecificName()` | returns a string in the format as described by a resolver (see below). |
+| `getDisplayName()` | convenience method returning a combination of the technical name appended by the class specific name. |
+
+### Class Specific Name Resolvers
+
+Calling `getClassSpecificName()` on an object with a defined name resolver
+allows for specific code to interpret the object (including referred) and
+return a more readable string description.
+
+For example if you call it on an `IObject` representing a `java.lang.String`,
+then it will return the value of the string.
+
+If you call it on an `IObject` representing a `java.lang.Thread`, it will return
+the name of the Thread. This method however is not the toString() method of the
+real objects that were put in the heap dump. The heap dump only contains the
+objects and their values, but it is not possible to call methods of the
+corresponding classes. The Memory Analyzer extracts information from the fields
+of the objects and models the toString() behavior.
+
+It is possible to easily extend MAT by adding new ClassSpecificNameResolvers
+using a defined extension point. The existing resolvers are available in
+`org.eclipse.mat.inspections.*` package. You can register or contribute
+additional resolvers to support a more pleasant experience.
+
+See the relevant section in [Extending Memory Analyzer](Extending_Memory_Analyzer.md)
+
+## Object sizes
+
+### Shallow size
+
+To get the shallow size of a single object, use the `getHeapSize` method of
+`ISnapshot`:
+
+```java
+ public long getHeapSize(int objectId) throws SnapshotException;
+```
+
+If you have to compute the shallow size of a set of objects (e.g. the sum of the
+shallow sizes of each instance of a certain class), then we recommend to use the
+`getHeapSize(int[] objectIds)` method of ISnapshot and pass the ids of all
+objects of interest as an array. This method uses some internal structures and
+is executing the task in several threads (if more than one CPU is available),
+therefore it will have better performance than looping over the objects and
+calling `getHeapSize()` for each single object.
+
+### Retained Size
+
+To get the retained size of a single object, use the `getRetainedHeapSize()`
+method of ISnapshot.
+
+```java
+ public long getRetainedHeapSize(int objectId) throws SnapshotException;
+```
+
+To get the retained size of a set of objects, first compute the retained set
+using `int[] getRetainedSet(int[], IProgressListener)` and then call the
+`getHeapSize(int[])` on the returned array with ids.
+
+The `getRetainedSet` method has two other “advanced” variants. Consult the API
+reference inside the tool for more details.