diff --git a/docs/usersguide/accessing.rst b/docs/usersguide/accessing.rst
index 65e16febd..343c18886 100644
--- a/docs/usersguide/accessing.rst
+++ b/docs/usersguide/accessing.rst
@@ -1,2 +1,187 @@
+.. _accessing_content:
+
 Accessing content
 =================
+
+JSON representation
+-------------------
+
+Records are internally stored in JSON following a certain JSON Schema.
+They can be obtained using REST API to records.
+
+Using CLI:
+
+.. code-block:: console
+
+   $ curl http://192.168.50.10/api/records/117
+   {
+
+       "created": "2017-03-21T00:01:27.933711+00:00",
+       "id": 117,
+       "links": {
+           "self": "http://192.168.50.10/api/records/117"
+       },
+       "metadata": {
+           "__order__": [
+               "title_statement",
+               "main_entry_personal_name"
+           ],
+           "_oai": {
+               "id": "oai:invenio:recid/118",
+               "updated": "2017-03-21T00:01:27Z"
+           },
+           "control_number": "118",
+           "main_entry_personal_name": {
+               "__order__": [
+                   "personal_name"
+               ],
+               "personal_name": "Doe, John"
+           },
+           "title_statement": {
+               "__order__": [
+                   "title"
+               ],
+               "title": "This is title"
+           }
+       },
+       "updated": "2017-03-21T00:01:27.933721+00:00"
+
+   }
+
+Using Python:
+
+.. code-block:: console
+
+   $ ipython
+   In [1]: import requests
+   In [2]: r = requests.get('http://192.168.50.10/api/records/117')
+   In [3]: r.status_code
+   Out[3]: 200
+   In [4]: r.json()
+   Out[4]:
+   {'created': '2017-03-21T00:01:27.933711+00:00',
+    'id': 117,
+    'links': {'self': 'http://192.168.50.10/api/records/117'},
+    'metadata': {'__order__': ['title_statement', 'main_entry_personal_name'],
+     '_oai': {'id': 'oai:invenio:recid/118', 'updated': '2017-03-21T00:01:27Z'},
+     'control_number': '118',
+     'main_entry_personal_name': {'__order__': ['personal_name'],
+      'personal_name': 'Doe, John'},
+     'title_statement': {'__order__': ['title'], 'title': 'This is title'}},
+    'updated': '2017-03-21T00:01:27.933721+00:00'}
+
+Multiple output formats
+-----------------------
+
+You can obtain information in other formats by setting an appropriate Accept
+header. Invenio REST API endpoint will read this information and invoke
+appropriate record serialisation. For example, to obtain a BibTeX representation
+of a record:
+
+.. code-block:: console
+
+   $ curl -H 'Accept: application/x-bibtex' https://zenodo.org/api/records/46643
+   @misc{himpe_2016_46643,
+     author       = {Himpe, Christian and
+                     Ohlberger, Mario},
+     title        = {{Accelerating the Computation of Empirical Gramians
+                      and Related Methods}},
+     month        = feb,
+     year         = 2016,
+     note         = {Extended Abstract},
+     doi          = {10.5281/zenodo.46643},
+     url          = {https://doi.org/10.5281/zenodo.46643}
+
+Getting record fields
+---------------------
+
+Getting title
+~~~~~~~~~~~~~
+
+If we would like to obtain only some part of information, for example record
+title, we can simply filter the output fields.
+
+Using CLI:
+
+.. code-block:: console
+
+   $ curl -s http://192.168.50.10/api/records/117 | \
+     jq -r '.metadata.title_statement.title'
+   This is title
+
+Using Python:
+
+.. code-block:: console
+
+   $ ipython
+   In [1]: import requests
+   In [2]: r = requests.get('http://192.168.50.10/api/records/117')
+   In [3]: r.json()['metadata'].get('title_statement',{}).get('title','')
+   Out[3]: 'This is title'
+
+Getting co-authors
+~~~~~~~~~~~~~~~~~~
+
+If we would like to print all co-author names, we can iterate over respective
+JSON field as follows:
+
+Using CLI:
+
+.. code-block:: console
+
+   $ curl -s http://192.168.50.10/api/records/97 | \
+     jq -r '.metadata.added_entry_personal_name[].personal_name'
+   Lokajczyk, T
+   Xu, W
+   Jastrow, U
+   Hahn, U
+   Bittner, L
+   Feldhaus, J
+
+Using Python:
+
+.. code-block:: console
+
+   $ ipython
+   In [1]: import requests
+   In [2]: r = requests.get('http://192.168.50.10/api/records/97')
+   In [2]: for coauthor in r.json()['metadata']['added_entry_personal_name']:
+   ......:     print(coauthor['personal_name'])
+   Lokajczyk, T
+   Xu, W
+   Jastrow, U
+   Hahn, U
+   Bittner, L
+   Feldhaus, J
+
+Searching records
+-----------------
+
+Invenio instance can be searched programmatically via the REST API endpoint:
+
+.. code-block:: console
+
+   $ curl http://192.168.50.10/api/records?q=model
+
+Note the pagination of the output done by the "links" output field.
+
+How many records are there that contain the word "model"? We need to iterate
+over results:
+
+.. code-block:: Python
+
+    nb_hits = 0
+
+    def get_nb_hits(json_response):
+        return len(json_response['hits']['hits'])
+
+    def get_next_link(json_response):
+        return json_response['links'].get('next', None)
+
+    response = requests.get('http://192.168.50.10/api/records?q=model').json()
+    nb_hits += get_nb_hits(response)
+    while get_next_link(response):
+        response = requests.get(get_next_link(response)).json()
+        nb_hits += get_nb_hits(response)
+
+    print(nb_hits)
diff --git a/docs/usersguide/loading.rst b/docs/usersguide/loading.rst
index 2d47f0f79..b2f64352f 100644
--- a/docs/usersguide/loading.rst
+++ b/docs/usersguide/loading.rst
@@ -1,2 +1,121 @@
+.. _loading_content:
+
 Loading content
 ===============
+
+Loading records
+---------------
+
+In the Invenio demo site example using ILS flavour, we have seen the ``invenio
+marc21`` command that can load records directly from a MARCXML file.
+
+You can use ``dojson`` to convert MARCXML format to its JSON representation:
+
+.. code-block:: console
+
+   $ dojson -i book.xml -l marcxml do marc21 \
+       schema "http://192.168.50.10/schema/marc21/bibliographic/bd-v1.0.0.json" \
+      > book.json
+   $ cat book.json | jq .
+   [
+     {
+       "title_statement": {
+         "title": "This is title",
+         "__order__": [
+           "title"
+         ]
+       },
+       "main_entry_personal_name": {
+         "personal_name": "Doe, John",
+         "__order__": [
+           "personal_name"
+         ]
+       },
+       "__order__": [
+         "title_statement",
+         "main_entry_personal_name"
+       ],
+       "$schema": "http://192.168.50.10/schema/marc21/bibliographic/bd-v1.0.0.json"
+     }
+   ]
+
+You can load JSON records using the ``invenio records`` command:
+
+.. code-block:: console
+
+   $ cat book.json | invenio records create --pid-minter recid --pid-minter oaiid
+   efac2fc2-29af-40bb-a85e-77af0349c0fe
+
+The new record that we have just uploaded got the UUID
+efac2fc2-29af-40bb-a85e-77af0349c0fe that uniquely identifies it inside the
+Invenio record database. It was also minted persistent identifiers ``recid``
+representing record ID and ``oaiid`` representing OAI ID.
+
+UUIDs and PIDs
+--------------
+
+Objects managed by Invenio use "internal" UUID identifiers and "external"
+persistent identifiers (PIDs).
+
+Starting from a persistent identifier, you can see which UUID a persistent
+identifier points to by using the ``invenio pid`` command:
+
+.. code-block:: console
+
+   $ invenio pid get recid 117
+   rec a11dad76-5bd9-471c-975a-0b2b01d74831 R
+
+Starting from the UUID of a record, you can see which PIDs the record was
+assigned by doing:
+
+.. code-block:: console
+
+   $ invenio pid dereference rec a11dad76-5bd9-471c-975a-0b2b01d74831
+   recid 117 None
+   oai oai:invenio:recid/117 oai
+
+You can unassign persistent identifiers:
+
+.. code-block:: console
+
+   $ invenio pid unassign recid 117
+   R
+   $ invenio pid unassign oai oai:invenio:recid/117
+   R
+
+What happens when you try to access the given record ID?
+
+.. code-block:: console
+
+   $ firefox http://192.168.50.10/api/records/117
+
+You can assign another record the same PID:
+
+.. code-block:: console
+
+   $ invenio pid assign -s REGISTERED -t rec -i 29351009-5e6f-4754-95cb-508f89f4de39 recid 117
+
+What happens when you try to access the given record ID now?
+
+.. code-block:: console
+
+   $ firefox http://192.168.50.10/api/records/117
+
+Deleting records
+----------------
+
+If you want to delete a certain record, you can use:
+
+.. code-block:: console
+
+   $ invenio records delete -i efac2fc2-29af-40bb-a85e-77af0349c0fe
+
+Beware of any registered persistent identifiers, though.
+
+Loading files
+-------------
+
+Loading full-text files, such as PDF papers or CSV data files together with the
+records, will be addressed later.
+
+.. todo:: Describe records, files, buckets.
diff --git a/docs/usersguide/quickstart.rst b/docs/usersguide/quickstart.rst
index aff38b85b..528892cab 100644
--- a/docs/usersguide/quickstart.rst
+++ b/docs/usersguide/quickstart.rst
@@ -1,61 +1,63 @@
 ..  This file is part of Invenio
     Copyright (C) 2014, 2015, 2016, 2017 CERN.
 
     Invenio is free software; you can redistribute it and/or
     modify it under the terms of the GNU General Public License as
     published by the Free Software Foundation; either version 2 of the
     License, or (at your option) any later version.
 
     Invenio is distributed in the hope that it will be useful, but
     WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     General Public License for more details.
 
     You should have received a copy of the GNU General Public License
     along with Invenio; if not, write to the Free Software Foundation, Inc.,
     59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 
+.. _quickstart:
+
 Quickstart
 ==========
 
 Using Docker
 ------------
 
 You can get Invenio v3.0 demo site up and running using Docker::
 
   docker-compose build
   docker-compose up -d
   docker-compose run --rm web ./scripts/populate-instance.sh
   firefox http://127.0.0.1/records/1
 
 Using Vagrant
 -------------
 
 You can get Invenio v3.0 demo site up and running using Vagrant::
 
   vagrant up
   vagrant ssh web -c 'source .inveniorc && /vagrant/scripts/create-instance.sh'
   vagrant ssh web -c 'source .inveniorc && /vagrant/scripts/populate-instance.sh'
   vagrant ssh web -c 'source .inveniorc && nohup /vagrant/scripts/start-instance.sh'
   firefox http://192.168.50.10/records/1
 
 Using kickstart scripts
 -----------------------
 
 You can set some environment variables and run kickstart provisioning and
 installation scripts manually::
 
   vim .inveniorc
   source .inveniorc
   scripts/provision-web.sh
   scripts/provision-postgresql.sh
   scripts/provision-elasticsearch.sh
   scripts/provision-redis.sh
   scripts/provision-rabbitmq.sh
   scripts/provision-worker.sh
   scripts/create-instance.sh
   scripts/populate-instance.sh
   scripts/start-instance.sh
   firefox http://192.168.50.10/records/1
 
-See :ref:`installation_detailed` for more information.
+See :ref:`install_prerequisites` for more information.
diff --git a/docs/usersguide/running.rst b/docs/usersguide/running.rst
index b0224bfe2..2fa4c3af6 100644
--- a/docs/usersguide/running.rst
+++ b/docs/usersguide/running.rst
@@ -1,11 +1,162 @@
 Running Invenio
 ===============
 
+Understanding Invenio components
+--------------------------------
+
+Invenio dems site consists of many components. To see which ones the Invenio
+demo site uses, you can do:
+
+.. code-block:: console
+
+   $ pip freeze | grep invenio
+   invenio-access==1.0.0a11
+   invenio-accounts==1.0.0b3
+   invenio-admin==1.0.0b1
+   invenio-app==1.0.0a1
+   invenio-app-ils==1.0.0a2
+   invenio-assets==1.0.0b6
+   invenio-base==1.0.0a14
+   invenio-celery==1.0.0b2
+   invenio-config==1.0.0b3
+   invenio-db==1.0.0b3
+   invenio-formatter==1.0.0b1
+   invenio-i18n==1.0.0b3
+   invenio-indexer==1.0.0a9
+   invenio-jsonschemas==1.0.0a3
+   invenio-logging==1.0.0b1
+   invenio-mail==1.0.0b1
+   invenio-marc21==1.0.0a5
+   invenio-oaiserver==1.0.0a12
+   invenio-oauth2server==1.0.0a15
+   invenio-oauthclient==1.0.0a12
+   invenio-pidstore==1.0.0b1
+   invenio-query-parser==0.6.0
+   invenio-records==1.0.0b1
+   invenio-records-rest==1.0.0a18
+   invenio-records-ui==1.0.0a9
+   invenio-rest==1.0.0a10
+   invenio-search==1.0.0a9
+   invenio-search-ui==1.0.0a6
+   invenio-theme==1.0.0b2
+   invenio-userprofiles==1.0.0a9
+
 Starting the webserver
 ----------------------
 
-Starting job queue
-------------------
+The Invenio application server can be started using:
+
+.. code-block:: bash
+
+   invenio run -h 0.0.0.0
+
+For debugging purposes, you can use:
+
+.. code-block:: bash
+
+   pip install Flask-DebugToolbar
+   FLASK_DEBUG=1 invenio run --debugger -h 0.0.0.0
+
+Starting the job queue
+----------------------
+
+Invenio uses Celery for task execution. The task queue should be started as
+follows:
+
+.. code-block:: bash
+
+   celery worker -A invenio_app.celery
+
+For debugging purposes, you can increse logging level:
+
+.. code-block:: bash
+
+   celery worker -A invenio_app.celery -l DEBUG
 
 Using the CLI
 -------------
+
+Invenio comes with centralised command line.  Use ``--help`` to see available commands:
+
+.. code-block:: console
+
+   $ invenio --help
+   Usage: invenio [OPTIONS] COMMAND [ARGS]...
+
+     Command Line Interface for Invenio.
+
+   Options:
+     --version  Show the flask version
+     --help     Show this message and exit.
+
+   Commands:
+     access    Account commands.
+     alembic   Perform database migrations.
+     assets    Web assets commands.
+     collect   Collect static files.
+     db        Database commands.
+     demo      Demo-site commands.
+     index     Management command for search indicies.
+     instance  Instance commands.
+     marc21    MARC21 related commands.
+     npm       Generate a package.json file.
+     pid       PID-Store management commands.
+     records   Record management commands.
+     roles     Role commands.
+     run       Runs a development server.
+     shell     Runs a shell in the app context.
+     users     User commands.
+
+You can use ``--help`` for each individual command, for example:
+
+.. code-block:: console
+
+    $ invenio marc21 import --help
+    Usage: invenio marc21 import [OPTIONS] INPUT
+
+      Import MARCXML records.
+
+    Options:
+      --bibliographic
+      --authority
+      --help           Show this message and exit.
+
+Using Python shell
+------------------
+
+You can start interactive Python shell which will load the Invenio application
+context so that you can work with the instance:
+
+.. code-block:: console
+
+   $ invenio shell
+   Python 2.7.6 (default, Oct 26 2016, 20:30:19)
+   [GCC 4.8.4] on linux2
+   App: invenio
+   Instance: /home/vagrant/.virtualenvs/invenio/var/instance
+   >>> app.config['BABEL_DEFAULT_LANGUAGE']
+   'en'
+   >>> app.config['BROKER_URL']
+   'amqp://guest:guest@192.168.50.10:5672//'
+
+Using administrative interface
+------------------------------
+
+You can access administrative interface:
+
+.. code-block:: console
+
+   $ firefox http://192.168.50.10/admin
+
+For example, let us look at the record ID 117 that we have uploaded in
+:ref:`create_and_search_your_first_record`. Looking at the administrative
+interface, we can see that this record has been attributed an internal UUID:
+
+  ======== ===================== ========== =========== ====================================
+  PID_Type PID                   Status     Object Type Object UUID
+  ======== ===================== ========== =========== ====================================
+  oai      oai:invenio:recid/117 REGISTERED rec         a11dad76-5bd9-471c-975a-0b2b01d74831
+  recid    117                   REGISTERED rec         a11dad76-5bd9-471c-975a-0b2b01d74831
+  ======== ===================== ========== =========== ====================================
+
+See :ref:`loading_content` for more information about object UUIDs and PIDs.
diff --git a/docs/usersguide/tutorial/configure.rst b/docs/usersguide/tutorial/configure.rst
new file mode 100644
index 000000000..acc26478f
--- /dev/null
+++ b/docs/usersguide/tutorial/configure.rst
@@ -0,0 +1,53 @@
+.. _configure_invenio:
+
+Configure Invenio
+=================
+
+After having installed Invenio demo site in :ref:`install_invenio`, let us see
+briefly the instance configuration.
+
+Configure instance
+------------------
+
+Invenio instance can be configured by editing ``invenio.cfg`` configuration
+file. Here is an example:
+
+.. code-block:: console
+
+   $ cdvirtualenv var/instance/
+   $ cat invenio.cfg
+   # Database
+   SQLALCHEMY_DATABASE_URI='postgresql+psycopg2://invenio:dbpass123@192.168.50.10:5432/invenio'
+
+   # Statis files
+   COLLECT_STORAGE='flask_collect.storage.file'
+
+   # Redis
+   CACHE_TYPE='redis'
+   CACHE_REDIS_HOST='192.168.50.10'
+   CACHE_REDIS_URL='redis://192.168.50.10:6379/0'
+   ACCOUNTS_SESSION_REDIS_URL='redis://192.168.50.10:6379/1'
+
+   # Celery
+   BROKER_URL='amqp://guest:guest@192.168.50.10:5672//'
+   CELERY_RESULT_BACKEND='redis://192.168.50.10:6379/2'
+
+   # Elasticsearch
+   SEARCH_ELASTIC_HOSTS='192.168.50.10'
+
+   # JSON Schema
+   JSONSCHEMAS_ENDPOINT='/schema'
+   JSONSCHEMAS_HOST='192.168.50.10'
+
+   # OAI server
+   OAISERVER_RECORD_INDEX='marc21'
+   OAISERVER_ID_PREFIX='oai:invenio:recid/'
+
+Configuration options
+---------------------
+
+Since Invenio demo site uses ILS flavour of Invenio, you can learn more about
+the configuration options in `Invenio-App-ILS configuration documentation
+<http://invenio-app-ils.readthedocs.io/en/latest/configuration.html>`_.
+
+We shall see how to customise instance more deeply in :ref:`customise_invenio`.
diff --git a/docs/usersguide/tutorial/customize.rst b/docs/usersguide/tutorial/customize.rst
index da8428938..3e08718ac 100644
--- a/docs/usersguide/tutorial/customize.rst
+++ b/docs/usersguide/tutorial/customize.rst
@@ -1,332 +1,336 @@
 ..
     This file is part of Invenio.
     Copyright (C) 2017 CERN.
 
     Invenio is free software; you can redistribute it
     and/or modify it under the terms of the GNU General Public License as
     published by the Free Software Foundation; either version 2 of the
     License, or (at your option) any later version.
 
     Invenio is distributed in the hope that it will be
     useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     General Public License for more details.
 
     You should have received a copy of the GNU General Public License
     along with Invenio; if not, write to the
     Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     MA 02111-1307, USA.
 
     In applying this license, CERN does not
     waive the privileges and immunities granted to it by virtue of its status
     as an Intergovernmental Organization or submit itself to any jurisdiction.
 
-Customization
-=============
+.. _customise_invenio:
 
-The goal of this tutorial is to customize Invenio v3.
+Customise Invenio
+=================
 
-Install
--------
+The goal of this tutorial is to demonstrate basic Invenio customisation. We
+shall modify the size logo, the page templates, the search facets, the sort
+options, and more.
+
+Install "beauty" module
+-----------------------
 
 First go in the virtual machine:
 
 .. code-block:: console
 
     laptop> vagrant ssh web
     vagrant> workon invenio
 
 
 Install the module ``invenio-beauty``:
 
 .. code-block:: console
 
     vagrant> cd /vagrant/2-customization/invenio-beauty
     vagrant> pip install .
     vagrant> invenio collect
     vagrant> invenio run -h 0.0.0.0
 
-Customize
----------
+Customize logo and templates
+----------------------------
 
 If you go to ``http://192.168.50.10/``, you will see the default Invenio,
 but how we can customize it? Let's first stop invenio server.
 
 Open with your favorite editor the ``~/.virtualenvs/invenio/var/instance/invenio.cfg``
 
 1. Modify the logo
 ^^^^^^^^^^^^^^^^^^
 Let's make our theme beautiful by replacing the logo
 
 in the ``~/.virtualenvs/invenio/var/instance/invenio.cfg`` add the following:
 
 .. code-block:: python
 
     THEME_LOGO = 'images/unicorn.png'
     THEME_FRONTPAGE_TITLE = 'Unicorn Institute'
 
 Now if you run
 
 .. code-block:: console
 
   vagrant> invenio run -h 0.0.0.0
 
 and navigate to ``http://192.168.50.10`` you will see the new logo and front
 page title.
 
 2. Add facets
 ^^^^^^^^^^^^^
 
 Let's replace the facets with the ``Authors`` adding the field
 ``main_entry_personal_name.personal_name``
 
 in the ``~/.virtualenvs/invenio/var/instance/invenio.cfg`` add the following:
 
 .. code-block:: python
 
     from invenio_records_rest.facets import terms_filter
 
     RECORDS_REST_FACETS = {
       'marc21': {
         'aggs': {
           'author': {
             'terms': {
               'field': 'main_entry_personal_name.personal_name'
             }
           }
         },
         'post_filters': {
           'author': terms_filter('main_entry_personal_name.personal_name')
         }
       }
     }
 
 Now if you run
 
 .. code-block:: console
 
   vagrant> invenio run -h 0.0.0.0
 
 and navigate to ``http://192.168.50.10/search`` you will see that the facets
 have been replaced with the ``Authors``.
 
 3. Add sort options
 ^^^^^^^^^^^^^^^^^^^
 
 in the ``~/.virtualenvs/invenio/var/instance/invenio.cfg`` add the following:
 
 .. code-block:: python
 
   RECORDS_REST_SORT_OPTIONS = {
     'records': {
       'title': {
         'fields': ['title_statement.title'],
         'title': 'Record title',
         'order': 1,
       }
     }
   }
 
 Now if you run
 
 .. code-block:: console
 
   vagrant> invenio run -h 0.0.0.0
 
 and navigate to ``http://192.168.50.10/search`` you will see that the sort list
 have been replaced with the ``Record title``.
 
 
 4. Change a detail view
 ^^^^^^^^^^^^^^^^^^^^^^^
 
 We will now replace the template for the detail view of the record, this is possible
 by changing ``RECORDS_UI_ENDPOINTS`` with the desired template. In our case
 we have created the following:
 
 in the ``/vagrant/2-customization/invenio-beauty/invenio_beauty/templates/detail.html``
 
 .. code-block:: python
 
   {%- extends config.RECORDS_UI_BASE_TEMPLATE %}
 
   {%- macro record_content(data) %}
     {% for key, value in data.items() recursive %}
       <li class="list-group-item">
       {% if value is mapping %}
           <strong>{{ key }}:</strong>
           <ul class="list-group">{{ loop(value.items()) }}</ul>
       {% elif value is iterable and value is not string %}
           <strong>{{ key }}:</strong>
           <ol>
           {% for item in value %}
             <li>
             {% if item is mapping %}
               <ul class="list-group">
                 {{ record_content(item) }}
               </ul>
             {% else %}
               {{ item }}
             {% endif %}
             </li>
           {% endfor %}
           </ol>
       {% else %}
         <strong>{{ key }}:</strong> {{ value }}
       {% endif %}
       </li>
     {% endfor %}
   {%- endmacro %}
 
   {%- block page_body %}
     <div class="container">
       <div class="row">
         <div class="col-md-12">
           <h2> {{ record.title_statement.title }}</h2>
           <hr />
           <p class="lead">{{ record.summary[0].summary }}</p>
           <hr />
           <h3> {{ _('Metadata') }}</h3>
           <div calss="well">
             {{ record_content(record) }}
           </div>
         </div>
       </div>
     </div>
   {%- endblock %}
 
 
 
 in the ``~/.virtualenvs/invenio/var/instance/invenio.cfg`` add the following:
 
 .. code-block:: python
 
   RECORDS_UI_ENDPOINTS = {
     "recid": {
         "pid_type": "recid",
         "route": "/records/<pid_value>",
         "template": "invenio_beauty/detail.html"
     },
   }
 
 Now if you run
 
 .. code-block:: console
 
   vagrant> invenio run -h 0.0.0.0
 
 and navigate to ``http://192.168.50.10/records/1`` you will see the new template.
 
 5. Modify search results template
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 We will now replace the search results template, in the search result we are
 using angular templates and they can easily configured from the following vars:
 
 - SEARCH_UI_JSTEMPLATE_COUNT
 - SEARCH_UI_JSTEMPLATE_ERROR
 - SEARCH_UI_JSTEMPLATE_FACETS
 - SEARCH_UI_JSTEMPLATE_RANGE
 - SEARCH_UI_JSTEMPLATE_LOADING
 - SEARCH_UI_JSTEMPLATE_PAGINATION
 - SEARCH_UI_JSTEMPLATE_RESULTS
 - SEARCH_UI_JSTEMPLATE_SELECT_BOX
 - SEARCH_UI_JSTEMPLATE_SORT_ORDER
 
 For our example we will change only ``SEARCH_UI_JSTEMPLATE_RESULTS``, the
 location of the angular templates are ``static/templates/<name of your module>``
 
 in ``/vagrant/2-customization/invenio-beauty/invenio_beauty/static/templates/invenio_beauty/results.html``
 
 .. code-block:: html
 
   <ol>
     <li ng-repeat="record in vm.invenioSearchResults.hits.hits track by $index">
       <span class="label label-success">{{ record.metadata.language_code[0].language_code_of_text_sound_track_or_separate_title[0] }}</span>
       <h4><a target="_self" ng-href="/records/{{ record.id }}">{{ record.metadata.title_statement.title }}</a></h4>
       <p>{{ record.metadata.summary[0].summary }}</p>
     </li>
   </ol>
 
 On the angular templates, you have access to the record metadata object, so in you templates
 you can use ``{{ record.metadata.foo }}``.
 
 Now in the search results template, we will display the language tag on top of each record
 ``language_code``.
 
 in the ``~/.virtualenvs/invenio/var/instance/invenio.cfg`` add the following:
 
 .. code-block:: python
 
   SEARCH_UI_JSTEMPLATE_RESULTS = 'templates/invenio_beauty/results.html'
 
 Now if you run
 
 .. code-block:: console
 
   vagrant> invenio collect -v
   vagrant> invenio run -h 0.0.0.0
 
 and navigate to ``http://192.168.50.10/search`` you will see the new template.
 
 6. Change the homepage template
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 We will now replace the demo's homepage. You can change the whole homepage just
 by replacing ``THEME_FRONTPAGE_TEMPLATE`` with your own template, for this
 example we have created the following:
 
 in ``/vagrant/2-customization/invenio-beauty/invenio_beauty/templates/invenio_beauty/home.html``
 
 .. code-block:: python
 
     {%- extends "invenio_theme/page.html" %}
 
     {%- block navbar_search %}{% endblock %}
     {%- block page_body %}
       <div class="container">
         <div class="row">
           <div class="col-lg-12">
             <h1 class="text-center">
               {{_(config.THEME_FRONTPAGE_TITLE)}} Search
             </h1>
             <form action="/search">
               <div class="form-group">
                 <input type="text" name="q" class="form-control" placeholder="Type and press enter to search">
               </div>
             </form>
           </div>
         </div>
       </div>
     {%- endblock %}
 
 If you have a closer look, you will see that we have access to different config
 variables on the template, by using the ``config``. For example if we want to
 display the ``THEME_FRONTPAGE_TITLE`` we can you ``config.THEME_FRONTPAGE_TITLE``
 
 So the only thing we should do is to edit the ``config.py``
 
 in the ``~/.virtualenvs/invenio/var/instance/invenio.cfg`` add the following:
 
 .. code-block:: python
 
   THEME_FRONTPAGE_TEMPLATE = 'invenio_beauty/home.html'
 
 
 Now if you run
 
 .. code-block:: console
 
   vagrant> invenio run -h 0.0.0.0
 
 and navigate to ``http://192.168.50.10`` you will see the new template.
 
 Everything together
 -------------------
 
 You want to see the results? Just run the following command.
 
 .. code-block:: console
 
     vagrant> cd /vagrant/iugw2017/2-customization
     vagrant> cat final.cfg >> ~/.virtualenvs/invenio/var/instance/invenio.cfg
diff --git a/docs/usersguide/tutorial/index.rst b/docs/usersguide/tutorial/index.rst
index c479d187f..4567bedfb 100644
--- a/docs/usersguide/tutorial/index.rst
+++ b/docs/usersguide/tutorial/index.rst
@@ -1,28 +1,29 @@
 .. This file is part of Invenio
-   Copyright (C) 2015 CERN.
+   Copyright (C) 2015, 2017 CERN.
 
    Invenio is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
    published by the Free Software Foundation; either version 2 of the
    License, or (at your option) any later version.
 
    Invenio is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with Invenio; if not, write to the Free Software Foundation, Inc.,
    59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 
 
 First steps
 ===========
 
 .. toctree::
    :maxdepth: 2
 
    prerequisites
    install
+   configure
    records
    customize
diff --git a/docs/usersguide/tutorial/install.rst b/docs/usersguide/tutorial/install.rst
index 3ae67cb27..f49a3abd3 100644
--- a/docs/usersguide/tutorial/install.rst
+++ b/docs/usersguide/tutorial/install.rst
@@ -1,2 +1,141 @@
-Part 1: Install and configuring Invenio
-=======================================
+.. _install_invenio:
+
+Install Invenio
+===============
+
+Now that all the prerequisites have been set up in :ref:`install_prerequisites`,
+we can proceed with the installation of the Invenio itself. The installation is
+happening on the web node (192.168.50.10).
+
+We start by creating and configuring a new Invenio instance, continue by
+populating it with some example records, and finally we start the web
+application. This can be done in an automated unattended way by running the
+following scripts:
+
+.. code-block:: shell
+
+   source .inveniorc
+   ./scripts/create-instance.sh
+   ./scripts/populate-instance.sh
+   ./scripts/start-instance.sh
+
+.. note::
+
+   If you want to install the very-bleeding-edge Invenio packages from GitHub,
+   you can run the ``create-instance.sh`` script with the ``--devel`` argument::
+
+     ./scripts/create-instance.sh --devel
+
+Let’s see in detail about every Invenio installation step.
+
+Create instance
+~~~~~~~~~~~~~~~
+
+We start by creating a fresh new Python virtual environment that will hold our
+brand new Invenio v3.0 instance:
+
+.. include:: ../../../scripts/create-instance.sh
+   :start-after: # sphinxdoc-create-virtual-environment-begin
+   :end-before: # sphinxdoc-create-virtual-environment-end
+   :literal:
+
+We continue by installing Invenio v3.0 Integrated Library System flavour demo
+site from PyPI:
+
+.. include:: ../../../scripts/create-instance.sh
+   :start-after: # sphinxdoc-install-invenio-full-begin
+   :end-before: # sphinxdoc-install-invenio-full-end
+   :literal:
+
+Let's briefly customise our instance with respect to the location of the
+database server, the Redis server, the Elasticsearch server, and all the other
+dependent services in our multi-server environment:
+
+.. include:: ../../../scripts/create-instance.sh
+   :start-after: # sphinxdoc-customise-instance-begin
+   :end-before: # sphinxdoc-customise-instance-end
+   :literal:
+
+In the instance folder, we run Npm to install any JavaScript libraries that
+Invenio needs:
+
+.. include:: ../../../scripts/create-instance.sh
+   :start-after: # sphinxdoc-run-npm-begin
+   :end-before: # sphinxdoc-run-npm-end
+   :literal:
+
+We can now collect and build CSS/JS assets of our Invenio instance:
+
+.. include:: ../../../scripts/create-instance.sh
+   :start-after: # sphinxdoc-collect-and-build-assets-begin
+   :end-before: # sphinxdoc-collect-and-build-assets-end
+   :literal:
+
+Our first new Invenio instance is created and ready for loading some example
+records.
+
+Populate instance
+~~~~~~~~~~~~~~~~~
+
+We proceed by creating a dedicated database that will hold persistent data of
+our installation, such as bibliographic records or user accounts. The database
+tables can be created as follows:
+
+.. include:: ../../../scripts/populate-instance.sh
+   :start-after: # sphinxdoc-create-database-begin
+   :end-before: # sphinxdoc-create-database-end
+   :literal:
+
+We continue by creating a user account:
+
+.. include:: ../../../scripts/populate-instance.sh
+   :start-after: # sphinxdoc-create-user-account-begin
+   :end-before: # sphinxdoc-create-user-account-end
+   :literal:
+
+We can now create the Elasticsearch indexes and initialise the indexing queue:
+
+.. include:: ../../../scripts/populate-instance.sh
+   :start-after: # sphinxdoc-index-initialisation-begin
+   :end-before: # sphinxdoc-index-initialisation-end
+   :literal:
+
+We proceed by populating our Invenio demo instance with some example demo
+MARCXML records:
+
+.. include:: ../../../scripts/populate-instance.sh
+   :start-after: # sphinxdoc-populate-with-demo-records-begin
+   :end-before: # sphinxdoc-populate-with-demo-records-end
+   :literal:
+
+Start instance
+~~~~~~~~~~~~~~
+
+Let's now start the web application:
+
+.. include:: ../../../scripts/start-instance.sh
+   :start-after: # sphinxdoc-start-application-begin
+   :end-before: # sphinxdoc-start-application-end
+   :literal:
+
+and the web server:
+
+.. include:: ../../../scripts/start-instance.sh
+   :start-after: # sphinxdoc-start-nginx-begin
+   :end-before: # sphinxdoc-start-nginx-end
+   :literal:
+
+We should now see our demo records on the web:
+
+.. code-block:: shell
+
+   firefox http://${INVENIO_WEB_HOST}/records/1
+
+and we can access them via REST API:
+
+.. code-block:: shell
+
+   curl -i -H "Accept: application/json" \
+        http://${INVENIO_WEB_HOST}/api/records/1
+
+We are done! Our first Invenio v3.0 demo instance is fully up and running.
diff --git a/docs/usersguide/tutorial/prerequisites.rst b/docs/usersguide/tutorial/prerequisites.rst
index 5a14fd0ba..35e4529f3 100644
--- a/docs/usersguide/tutorial/prerequisites.rst
+++ b/docs/usersguide/tutorial/prerequisites.rst
@@ -1,2 +1,510 @@
+.. _install_prerequisites:
+
 Install prerequisites
 =====================
+
+Overview
+--------
+
+Invenio uses several services such as `PostgreSQL <http://www.postgresql.org/>`_
+database server, `Redis <http://redis.io/>`_ for caching, `Elasticsearch
+<https://www.elastic.co/products/elasticsearch>`_ for indexing and information
+retrieval, `RabbitMQ <http://www.rabbitmq.com/>`_ for messaging, `Celery
+<http://www.celeryproject.org/>`_ for task execution.
+
+You can install them manually or you can use provided kickstart scripts as
+mentioned in :ref:`quickstart`:
+
+.. code-block:: bash
+
+  vim .inveniorc
+  source .inveniorc
+  scripts/provision-web.sh
+  scripts/provision-postgresql.sh
+  scripts/provision-elasticsearch.sh
+  scripts/provision-redis.sh
+  scripts/provision-rabbitmq.sh
+  scripts/provision-worker.sh
+
+The next section gives a detailed walk-through of what the scripts do.
+
+Concrete example
+----------------
+
+In this installation example, we'll create an Invenio digital library instance
+using a multi-machine setup where separate services (such as the database server
+and the web server) run on separate dedicated machines. Such a multi-machine
+setup emulates to what one would typically use in production. (However, it is
+very well possible to follow this guide and install all the services onto the
+same "localhost", if one wants to.)
+
+We'll use six dedicated machines running the following services:
+
+============= ============= ====================
+node          IP            runs
+============= ============= ====================
+web           192.168.50.10 Invenio web application
+postgresql    192.168.50.11 `PostgreSQL <http://www.postgresql.org/>`_ database server
+redis         192.168.50.12 `Redis <http://redis.io/>`_ caching service
+elasticsearch 192.168.50.13 `Elasticsearch <https://www.elastic.co/products/elasticsearch>`_ information retrieval service
+rabbitmq      192.168.50.14 `RabbitMQ <http://www.rabbitmq.com/>`_ messaging service
+worker        192.168.50.15 `Celery <http://www.celeryproject.org/>`_ worker node
+============= ============= ====================
+
+The instructions below are tested on Ubuntu 14.04 LTS (Trusty Tahr) and CentOS 7
+operating systems. For other operating systems such as Mac OS X, you may want to
+check out the "kickstart" set of scripts coming with the Invenio source code
+that perform the below-quoted installation steps in an unattended automated way.
+
+Environment variables
+~~~~~~~~~~~~~~~~~~~~~
+
+Let's define some useful environment variables that will describe our Invenio
+instance setup:
+
+.. glossary::
+
+   INVENIO_WEB_HOST
+     The IP address of the Web server node.
+
+   INVENIO_WEB_INSTANCE
+     The name of your Invenio instance that will be created. Usually equal to
+     the name of the Python virtual environment.
+
+   INVENIO_WEB_VENV
+     The name of the Python virtual environment where Invenio will be installed.
+     Usually equal to the name of the Invenio instance.
+
+   INVENIO_USER_EMAIL
+     The email address of a user account that will be created on the Invenio
+     instance.
+
+   INVENIO_USER_PASS
+     The password of this Invenio user.
+
+   INVENIO_POSTGRESQL_HOST
+     The IP address of the PostgreSQL database server.
+
+   INVENIO_POSTGRESQL_DBNAME
+     The database name that will hold persistent data of our Invenio instance.
+
+   INVENIO_POSTGRESQL_DBUSER
+     The database user name used to connect to the database server.
+
+   INVENIO_POSTGRESQL_DBPASS
+     The password of this database user.
+
+   INVENIO_REDIS_HOST
+     The IP address af the Redis server.
+
+   INVENIO_ELASTICSEARCH_HOST
+     The IP address of the Elasticsearch information retrieval server.
+
+   INVENIO_RABBITMQ_HOST
+     The IP address of the RabbitMQ messaging server.
+
+   INVENIO_WORKER_HOST
+     The IP address of the Celery worker node.
+
+In our example setup, we shall use:
+
+.. include:: ../../../.inveniorc
+   :start-after: # sphinxdoc-kickstart-configuration-variables-begin
+   :end-before: # sphinxdoc-kickstart-configuration-variables-end
+   :literal:
+
+Let us save this configuration in a file called ``.inveniorc`` for future use.
+
+Web
+~~~
+
+The web application node (192.168.50.10) is where the main Invenio application
+will be running. We need to provision it with some system dependencies in order
+to be able to install various underlying Python and JavaScript libraries.
+
+The web application node can be set up in an automated unattended way by running
+the following script:
+
+.. code-block:: shell
+
+   source .inveniorc
+   ./scripts/provision-web.sh
+
+Let's see in detail what the web provisioning script does.
+
+First, let's see if using ``sudo`` will be required:
+
+.. include:: ../../../scripts/provision-web.sh
+   :start-after: # sphinxdoc-install-detect-sudo-begin
+   :end-before: # sphinxdoc-install-detect-sudo-end
+   :literal:
+
+Second, some useful system tools are installed:
+
+* on Ubuntu 14.04 LTS (Trusty Tahr):
+
+.. include:: ../../../scripts/provision-web.sh
+   :start-after: # sphinxdoc-install-useful-system-tools-ubuntu14-begin
+   :end-before: # sphinxdoc-install-useful-system-tools-ubuntu14-end
+   :literal:
+
+* on CentOS 7:
+
+.. include:: ../../../scripts/provision-web.sh
+   :start-after: # sphinxdoc-install-useful-system-tools-centos7-begin
+   :end-before: # sphinxdoc-install-useful-system-tools-centos7-end
+   :literal:
+
+Third, an external Node.js package repository is enabled. We'll be needing to
+install and run Npm on the web node later. The Node.js repository is enabled as
+follows:
+
+* on Ubuntu 14.04 LTS (Trusty Tahr):
+
+.. include:: ../../../scripts/provision-web.sh
+   :start-after: # sphinxdoc-add-nodejs-external-repository-ubuntu14-begin
+   :end-before: # sphinxdoc-add-nodejs-external-repository-ubuntu14-end
+   :literal:
+
+* on CentOS 7:
+
+.. include:: ../../../scripts/provision-web.sh
+   :start-after: # sphinxdoc-add-nodejs-external-repository-centos7-begin
+   :end-before: # sphinxdoc-add-nodejs-external-repository-centos7-end
+   :literal:
+
+Fourth, all the common prerequisite software libraries and packages that Invenio
+needs are installed:
+
+* on Ubuntu 14.04 LTS (Trusty Tahr):
+
+.. include:: ../../../scripts/provision-web.sh
+   :start-after: # sphinxdoc-install-web-common-ubuntu14-begin
+   :end-before: # sphinxdoc-install-web-common-ubuntu14-end
+   :literal:
+
+* on CentOS7:
+
+.. include:: ../../../scripts/provision-web.sh
+   :start-after: # sphinxdoc-install-web-common-centos7-begin
+   :end-before: # sphinxdoc-install-web-common-centos7-end
+   :literal:
+
+We want to use PostgreSQL database in this installation example, so we need to
+install corresponding libraries too:
+
+* on Ubuntu 14.04 LTS (Trusty Tahr):
+
+.. include:: ../../../scripts/provision-web.sh
+   :start-after: # sphinxdoc-install-web-libpostgresql-ubuntu14-begin
+   :end-before: # sphinxdoc-install-web-libpostgresql-ubuntu14-end
+   :literal:
+
+* on CentOS7:
+
+.. include:: ../../../scripts/provision-web.sh
+   :start-after: # sphinxdoc-install-web-libpostgresql-centos7-begin
+   :end-before: # sphinxdoc-install-web-libpostgresql-centos7-end
+   :literal:
+
+Fifth, now that Node.js is installed, we can proceed with installing Npm and
+associated CSS/JS filter tools. Let's do it globally:
+
+* on either of the operating systems:
+
+.. include:: ../../../scripts/provision-web.sh
+   :start-after: # sphinxdoc-install-npm-and-css-js-filters-begin
+   :end-before: # sphinxdoc-install-npm-and-css-js-filters-end
+   :literal:
+
+Sixth, we'll install Python virtual environment wrapper tools and activate them
+in the current user shell process:
+
+* on either of the operating systems:
+
+.. include:: ../../../scripts/provision-web.sh
+   :start-after: # sphinxdoc-install-virtualenvwrapper-begin
+   :end-before: # sphinxdoc-install-virtualenvwrapper-end
+   :literal:
+
+Seventh, we install Nginx web server and configure appropriate virtual host:
+
+* on Ubuntu 14.04 LTS (Trusty Tahr):
+
+.. include:: ../../../scripts/provision-web.sh
+   :start-after: # sphinxdoc-install-web-nginx-ubuntu14-begin
+   :end-before: # sphinxdoc-install-web-nginx-ubuntu14-end
+   :literal:
+
+* on CentOS7:
+
+.. include:: ../../../scripts/provision-web.sh
+   :start-after: # sphinxdoc-install-web-nginx-centos7-begin
+   :end-before: # sphinxdoc-install-web-nginx-centos7-end
+   :literal:
+
+Finally, let's clean after ourselves:
+
+* on Ubuntu 14.04 LTS (Trusty Tahr):
+
+.. include:: ../../../scripts/provision-web.sh
+   :start-after: # sphinxdoc-install-web-cleanup-ubuntu14-begin
+   :end-before: # sphinxdoc-install-web-cleanup-ubuntu14-end
+   :literal:
+
+* on CentOS7:
+
+.. include:: ../../../scripts/provision-web.sh
+   :start-after: # sphinxdoc-install-web-cleanup-centos7-begin
+   :end-before: # sphinxdoc-install-web-cleanup-centos7-end
+   :literal:
+
+Database
+~~~~~~~~
+
+The database server (192.168.50.11) will hold persistent data of our Invenio
+installation, such as bibliographic records or user accounts. Invenio supports
+MySQL, PostgreSQL, and SQLite databases. In this tutorial, we shall use
+PostgreSQL that is the recommended database platform for Invenio.
+
+The database server node can be set up in an automated unattended way by running
+the following script:
+
+.. code-block:: shell
+
+   source .inveniorc
+   ./scripts/provision-postgresql.sh
+
+Let's see in detail what the database provisioning script does.
+
+First, we install and configure the database software:
+
+* on Ubuntu 14.04 LTS (Trusty Tahr):
+
+.. include:: ../../../scripts/provision-postgresql.sh
+   :start-after: # sphinxdoc-install-postgresql-ubuntu14-begin
+   :end-before: # sphinxdoc-install-postgresql-ubuntu14-end
+   :literal:
+
+* on CentOS 7:
+
+.. include:: ../../../scripts/provision-postgresql.sh
+   :start-after: # sphinxdoc-install-postgresql-centos7-begin
+   :end-before: # sphinxdoc-install-postgresql-centos7-end
+   :literal:
+
+We can now create a new database user with the necessary access permissions on
+the new database:
+
+* on either of the operating systems:
+
+.. include:: ../../../scripts/provision-postgresql.sh
+   :start-after: # sphinxdoc-setup-postgresql-access-begin
+   :end-before: # sphinxdoc-setup-postgresql-access-end
+   :literal:
+
+Finally, let's clean after ourselves:
+
+* on Ubuntu 14.04 LTS (Trusty Tahr):
+
+.. include:: ../../../scripts/provision-postgresql.sh
+   :start-after: # sphinxdoc-install-postgresql-cleanup-ubuntu14-begin
+   :end-before: # sphinxdoc-install-postgresql-cleanup-ubuntu14-end
+   :literal:
+
+* on CentOS7:
+
+.. include:: ../../../scripts/provision-postgresql.sh
+   :start-after: # sphinxdoc-install-postgresql-cleanup-centos7-begin
+   :end-before: # sphinxdoc-install-postgresql-cleanup-centos7-end
+   :literal:
+
+Redis
+~~~~~
+
+The Redis server (192.168.50.12) is used for various caching needs.
+
+The Redis server can be set up in an automated unattended way by running the
+following script:
+
+.. code-block:: shell
+
+   source .inveniorc
+   ./scripts/provision-redis.sh
+
+Let's see in detail what the Redis provisioning script does.
+
+* on Ubuntu 14.04 LTS (Trusty Tahr):
+
+.. include:: ../../../scripts/provision-redis.sh
+   :start-after: # sphinxdoc-install-redis-ubuntu14-begin
+   :end-before: # sphinxdoc-install-redis-ubuntu14-end
+   :literal:
+
+* on CentOS 7:
+
+.. include:: ../../../scripts/provision-redis.sh
+   :start-after: # sphinxdoc-install-redis-centos7-begin
+   :end-before: # sphinxdoc-install-redis-centos7-end
+   :literal:
+
+Finally, let's clean after ourselves:
+
+* on Ubuntu 14.04 LTS (Trusty Tahr):
+
+.. include:: ../../../scripts/provision-redis.sh
+   :start-after: # sphinxdoc-install-redis-cleanup-ubuntu14-begin
+   :end-before: # sphinxdoc-install-redis-cleanup-ubuntu14-end
+   :literal:
+
+* on CentOS7:
+
+.. include:: ../../../scripts/provision-redis.sh
+   :start-after: # sphinxdoc-install-redis-cleanup-centos7-begin
+   :end-before: # sphinxdoc-install-redis-cleanup-centos7-end
+   :literal:
+
+Elasticsearch
+~~~~~~~~~~~~~
+
+The Elasticsearch server (192.168.50.13) is used to index and search
+bibliographic records, fulltext documents, and other various interesting
+information managed by our Invenio digital library instance.
+
+The Elasticsearch server can be set up in an automated unattended way by running
+the following script:
+
+.. code-block:: shell
+
+   source .inveniorc
+   ./scripts/provision-elasticsearch.sh
+
+Let's see in detail what the Elasticsearch provisioning script does.
+
+* on Ubuntu 14.04 LTS (Trusty Tahr):
+
+.. include:: ../../../scripts/provision-elasticsearch.sh
+   :start-after: # sphinxdoc-install-elasticsearch-ubuntu14-begin
+   :end-before: # sphinxdoc-install-elasticsearch-ubuntu14-end
+   :literal:
+
+* on CentOS 7:
+
+.. include:: ../../../scripts/provision-elasticsearch.sh
+   :start-after: # sphinxdoc-install-elasticsearch-centos7-begin
+   :end-before: # sphinxdoc-install-elasticsearch-centos7-end
+   :literal:
+
+Some packages require extra plugins to be installed.
+
+.. include:: ../../../scripts/provision-elasticsearch.sh
+   :start-after: # sphinxdoc-install-elasticsearch-plugins-begin
+   :end-before: # sphinxdoc-install-elasticsearch-plugins-end
+   :literal:
+
+Finally, let's clean after ourselves:
+
+* on Ubuntu 14.04 LTS (Trusty Tahr):
+
+.. include:: ../../../scripts/provision-elasticsearch.sh
+   :start-after: # sphinxdoc-install-elasticsearch-cleanup-ubuntu14-begin
+   :end-before: # sphinxdoc-install-elasticsearch-cleanup-ubuntu14-end
+   :literal:
+
+* on CentOS7:
+
+.. include:: ../../../scripts/provision-elasticsearch.sh
+   :start-after: # sphinxdoc-install-elasticsearch-cleanup-centos7-begin
+   :end-before: # sphinxdoc-install-elasticsearch-cleanup-centos7-end
+   :literal:
+
+RabbitMQ
+~~~~~~~~
+
+The RabbitMQ server (192.168.50.14) is used as a messaging middleware broker.
+
+The RabbitMQ server can be set up in an automated unattended way by running the
+following script:
+
+.. code-block:: shell
+
+   source .inveniorc
+   ./scripts/provision-rabbitmq.sh
+
+Let's see in detail what the RabbitMQ provisioning script does.
+
+* on Ubuntu 14.04 LTS (Trusty Tahr):
+
+.. include:: ../../../scripts/provision-rabbitmq.sh
+   :start-after: # sphinxdoc-install-rabbitmq-ubuntu14-begin
+   :end-before: # sphinxdoc-install-rabbitmq-ubuntu14-end
+   :literal:
+
+* on CentOS 7:
+
+.. include:: ../../../scripts/provision-rabbitmq.sh
+   :start-after: # sphinxdoc-install-rabbitmq-centos7-begin
+   :end-before: # sphinxdoc-install-rabbitmq-centos7-end
+   :literal:
+
+Finally, let's clean after ourselves:
+
+* on Ubuntu 14.04 LTS (Trusty Tahr):
+
+.. include:: ../../../scripts/provision-rabbitmq.sh
+   :start-after: # sphinxdoc-install-rabbitmq-cleanup-ubuntu14-begin
+   :end-before: # sphinxdoc-install-rabbitmq-cleanup-ubuntu14-end
+   :literal:
+
+* on CentOS7:
+
+.. include:: ../../../scripts/provision-rabbitmq.sh
+   :start-after: # sphinxdoc-install-rabbitmq-cleanup-centos7-begin
+   :end-before: # sphinxdoc-install-rabbitmq-cleanup-centos7-end
+   :literal:
+
+Worker
+~~~~~~
+
+The Celery worker node (192.168.50.15) is used to execute potentially long tasks
+in asynchronous manner.
+
+The worker node can be set up in an automated unattended way by running the
+following script:
+
+.. code-block:: shell
+
+   source .inveniorc
+   ./scripts/provision-worker.sh
+
+Let's see in detail what the worker provisioning script does.
+
+* on Ubuntu 14.04 LTS (Trusty Tahr):
+
+.. include:: ../../../scripts/provision-worker.sh
+   :start-after: # sphinxdoc-install-worker-ubuntu14-begin
+   :end-before: # sphinxdoc-install-worker-ubuntu14-end
+   :literal:
+
+* on CentOS 7:
+
+.. include:: ../../../scripts/provision-worker.sh
+   :start-after: # sphinxdoc-install-worker-centos7-begin
+   :end-before: # sphinxdoc-install-worker-centos7-end
+   :literal:
+
+Finally, let's clean after ourselves:
+
+* on Ubuntu 14.04 LTS (Trusty Tahr):
+
+.. include:: ../../../scripts/provision-worker.sh
+   :start-after: # sphinxdoc-install-worker-cleanup-ubuntu14-begin
+   :end-before: # sphinxdoc-install-worker-cleanup-ubuntu14-end
+   :literal:
+
+* on CentOS7:
+
+.. include:: ../../../scripts/provision-worker.sh
+   :start-after: # sphinxdoc-install-worker-cleanup-centos7-begin
+   :end-before: # sphinxdoc-install-worker-cleanup-centos7-end
+   :literal:
diff --git a/docs/usersguide/tutorial/records.rst b/docs/usersguide/tutorial/records.rst
index c1a13fcda..ac80a3cb5 100644
--- a/docs/usersguide/tutorial/records.rst
+++ b/docs/usersguide/tutorial/records.rst
@@ -1,2 +1,58 @@
-Part 2: Create and search your first record
-===========================================
+.. _create_and_search_your_first_record:
+
+Create and search your first record
+===================================
+
+Now that Invenio demo site has been installed in :ref:`install_invenio`, let us
+see how we can load some records.
+
+Upload a new record
+-------------------
+
+For the ILS flavour let us create a small example record in MARCXML format:
+
+.. code-block:: console
+
+   $ vim book.xml
+   $ cat book.xml
+   <?xml version="1.0" encoding="UTF-8"?>
+   <collection xmlns="http://www.loc.gov/MARC21/slim">
+   <record>
+     <datafield tag="245" ind1=" " ind2=" ">
+       <subfield code="a">This is title</subfield>
+     </datafield>
+     <datafield tag="100" ind1=" " ind2=" ">
+       <subfield code="a">Doe, John</subfield>
+     </datafield>
+   </record>
+   </collection>
+
+We can upload it by using ``invenio marc21 import`` command:
+
+.. code-block:: console
+
+   $ invenio marc21 import --bibliographic book.xml
+   Importing records
+   Created record 117
+   Indexing records
+
+Search for the record
+---------------------
+
+Let us verify that it was well uploaded:
+
+.. code-block:: console
+
+   $ firefox http://192.168.50.10/records/117
+
+and that it is well searchable:
+
+.. code-block:: console
+
+   $ firefox http://192.168.50.10/search?q=doe
+
+Uploading content
+-----------------
+
+For more information on how to upload content to an Invenio instance, see the
+documentation chapter on :ref:`loading_content`.