diff --git a/.travis.yml b/.travis.yml
index aef368d3de6f44dddbb59cb9cc4a78845e6084b0..301be92374b7baa47fd1483c1e3ebd0907dfb0af 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -11,21 +11,14 @@ before_install:
     - export PATH=/usr/lib/ccache:${PATH}
     - wget https://package-data.enthought.com/edm/rh5_x86_64/1.9/edm_1.9.2_linux_x86_64.sh && bash ./edm_1.9.2_linux_x86_64.sh -b -f -p $HOME
     - export PATH=${HOME}/edm/bin:${PATH}
-    - edm environments create --version ${PYTHON_VERSION} force
-    - . $HOME/.edm/envs/force/bin/activate
-install:
-    - pip install -r requirements/requirements.txt
-    - pip install -e .
+    - edm install -y -e force-bootstrap click setuptools
+    - edm run -e force-bootstrap -- python -m ci build-env --python-version ${PYTHON_VERSION}
 script:
-    - pip install -r requirements/dev_requirements.txt
-    - flake8 .
-    - python -m unittest discover
-    - pip install -r requirements/doc_requirements.txt
-    - pushd doc
-    - make html
-    - popd
+    - edm run -e force-bootstrap -- python -m ci flake8 --python-version ${PYTHON_VERSION}
+    - edm run -e force-bootstrap -- python -m ci test --python-version ${PYTHON_VERSION}
+    - edm run -e force-bootstrap -- python -m ci docs --python-version ${PYTHON_VERSION}
 after_success:
-    - coverage run -m unittest discover
-    - pip install codecov
-    - codecov
+    - edm run -e force-bootstrap -- python -m ci coverage --python-version ${PYTHON_VERSION}
+    - edm run -e force-bootstrap -- pip install codecov --python-version ${PYTHON_VERSION}
+    - edm run -e force-bootstrap -- codecov
     - bash <(curl -s https://codecov.io/bash)
diff --git a/ci/__init__.py b/ci/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/ci/__main__.py b/ci/__main__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e3d9daffef0c03e4507a0922086851fd76ebd93e
--- /dev/null
+++ b/ci/__main__.py
@@ -0,0 +1,114 @@
+import click
+from subprocess import check_call
+
+DEFAULT_PYTHON_VERSION = "2.7"
+PYTHON_VERSIONS = ["2.7", "3.5"]
+
+CORE_DEPS = [
+    "distribute_remove==1.0.0-4",
+    "pip==10.0.1-1",
+    "setuptools==38.2.5-1",
+    "envisage==4.6.0-1",
+    "click==6.7-1",
+    "six==1.10.0-1",
+]
+
+DOCS_DEPS = [
+    "sphinx==1.5.5-5"
+]
+
+DEV_DEPS = [
+    "flake8==3.3.0-2",
+    "coverage==4.3.4-1",
+    "mock==2.0.0-1",
+    "testfixtures==4.10.0-1",
+]
+
+PIP_DEPS = [
+    "stevedore==1.24.0"
+]
+
+
+@click.group()
+def cli():
+    pass
+
+
+python_version_option = click.option(
+    '--python-version',
+    default=DEFAULT_PYTHON_VERSION,
+    type=click.Choice(PYTHON_VERSIONS),
+    show_default=True,
+    help="Python version for the environment")
+
+
+@cli.command(name="build-env", help="Creates the execution environment")
+@python_version_option
+def build_env(python_version):
+    env_name = get_env_name(python_version)
+    check_call([
+        "edm", "environments", "remove", "--purge", "--force",
+        "--yes", env_name])
+    check_call(
+        ["edm", "environments", "create", env_name])
+
+    check_call([
+        "edm", "install", "-e", env_name,
+        "--yes"] + CORE_DEPS + DEV_DEPS + DOCS_DEPS)
+
+    if len(PIP_DEPS):
+        check_call([
+            "edm", "run", "-e", env_name, "--",
+            "pip", "install"] + PIP_DEPS)
+
+    check_call([
+        "edm", "run", "-e", env_name, "--",
+        "pip", "install", "-e", "."])
+
+
+@cli.command(help="Run the tests")
+@python_version_option
+def test(python_version):
+    env_name = get_env_name(python_version)
+
+    check_call([
+        "edm", "run", "-e", env_name, "--", "python", "-m", "unittest",
+        "discover"
+    ])
+
+
+@cli.command(help="Run flake")
+@python_version_option
+def flake8(python_version):
+    env_name = get_env_name(python_version)
+
+    check_call(["edm", "run", "-e", env_name, "--", "flake8", "."])
+
+
+@cli.command(help="Runs the coverage")
+@python_version_option
+def coverage(python_version):
+    env_name = get_env_name(python_version)
+
+    check_call(["edm", "run", "-e", env_name, "--",
+                "coverage", "run", "-m", "unittest", "discover"])
+
+
+@cli.command(help="Builds the documentation")
+@python_version_option
+def docs(python_version):
+    env_name = get_env_name(python_version)
+
+    check_call(["edm", "run", "-e", env_name, "--", "make", "html"], cwd="doc")
+
+
+def get_env_name(python_version):
+    return "force-py{}".format(remove_dot(python_version))
+
+
+def remove_dot(python_version):
+    return "".join(python_version.split('.'))
+
+
+if __name__ == "__main__":
+    cli()
diff --git a/doc/source/installation.rst b/doc/source/installation.rst
index 89cb78949799f94a7a9e0534bca9ddfda2799975..33b71b5ff699e730f1b6a03a9a7e9c7c5188fad0 100644
--- a/doc/source/installation.rst
+++ b/doc/source/installation.rst
@@ -10,40 +10,39 @@ git repositories::
 The last repository is optional, but recommended if you want to practice 
 writing plugins.
 
-Next, download EDM package manager, and create an appropriate 
-environment::
+Next, download EDM package manager, and create a bootstrap environment::
 
-    wget https://package-data.enthought.com/edm/rh5_x86_64/1.4/edm_1.4.1_linux_x86_64.sh && bash ./edm_1.4.1_linux_x86_64.sh -b -p $HOME
+    wget https://package-data.enthought.com/edm/rh5_x86_64/1.9/edm_1.9.2_linux_x86_64.sh && bash ./edm_1.9.2_linux_x86_64.sh -b -f -p $HOME
     export PATH=${HOME}/edm/bin:${PATH}
-    edm environments create --version 3.5 force 
-    edm shell --environment=force
+    edm environments create --version 3.5 force
+    edm install -y -e force-bootstrap click setuptools
+    edm shell --environment=force-bootstrap
 
-Veryfy that your prompt changes to add "(force)".
-Install the required packages for the workflow manager::
+Verify that your prompt changes to add "(force-bootstrap)".
+Installation of the force BDSS runtime environment is performed with the
+following command::
 
-    cat force-wfmanager/requirements/edm_requirements.txt | grep -v "^#" | while read line; do edm install -y `echo $line | awk '{print $1"=="$2}'`; done
+    python -m ci build-env
 
-Now, install the bdss::
+This will create another edm environment called ``force-py27``.
 
-    pushd force-bdss
-    pip install -r requirements/requirements.txt
-    pip install -e . 
-    popd
-
-the workflow manager::
+To install the workflow manager::
 
     pushd force-wfmanager
-    pip install -r requirements/requirements.txt
-    pip install -e .
+    python -m ci install
     popd
 
 and (optional, but recommended), the example plugins::
 
     pushd force-bdss-plugin-enthought-example
-    pip install -r requirements/requirements.txt
-    pip install -e .
+    python -m ci install
     popd
 
-Now you can invoke the workflow manager with force_wfmanager,
-and the bdss with force_bdss.
+Now you can enter the deployed environment and invoke the programs::
+
+    edm shell -e force-py27
+    # Invokes the workflow manager UI
+    force_wfmanager
+    # Invokes the CLI BDSS evaluator
+    force_bdss
 
diff --git a/requirements/dev_requirements.txt b/requirements/dev_requirements.txt
deleted file mode 100644
index 453d4d8a2717d98b6e8a03f97d798c5faccbc807..0000000000000000000000000000000000000000
--- a/requirements/dev_requirements.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-flake8
-coverage
-mock
-testfixtures
diff --git a/requirements/doc_requirements.txt b/requirements/doc_requirements.txt
deleted file mode 100644
index 7f3dca30339f07098bf1931c4bf36639e5533ac2..0000000000000000000000000000000000000000
--- a/requirements/doc_requirements.txt
+++ /dev/null
@@ -1 +0,0 @@
-sphinx >= 1.3.1
diff --git a/requirements/requirements.txt b/requirements/requirements.txt
deleted file mode 100644
index cfc27054ea4f3f6acf0be5267e8bf9a3809d9881..0000000000000000000000000000000000000000
--- a/requirements/requirements.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-envisage==4.6.0
-click==6.7
-six==1.10.0
-stevedore==1.24.0