diff --git a/.gitignore b/.gitignore
index 14c5a9ac64d55f7181966bff6cb3a83db67cd4d7..4529688adbfc84bf8e59c8d4c045cc972a0576f0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@
 /.pydevproject
 /cost_models/fuga/pascal_test
 snopt
+*.png
 
 # Byte-compiled / optimized / DLL files
 __pycache__/
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 7399b447073caf7c9546ac16b03e710b87d19f98..a88631be76c9fa73ab4cea52408f66a5478bd050 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -17,9 +17,6 @@
 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
 #
-# import os
-# import sys
-# sys.path.insert(0, os.path.abspath('.'))
 
 
 # -- General configuration ------------------------------------------------
@@ -180,3 +177,5 @@ intersphinx_mapping = {
 'pandas': ('http://pandas-docs.github.io/pandas-docs-travis', None),
 'numpy': ('http://docs.scipy.org/doc/numpy-1.13.0', None)
 }
+
+figure_language_filename = 'examples/{basename}{ext}'
diff --git a/docs/source/dev_guide/quick_guide.rst b/docs/source/dev_guide/quick_guide.rst
deleted file mode 100644
index 09203e2a8a7f38fe177a7f752514f259c8fa5e57..0000000000000000000000000000000000000000
--- a/docs/source/dev_guide/quick_guide.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-.. _quick_guide:
-
-=======================
-Quick Reference
-=======================
-
-1. Do this first.  
-2. Then do this.  
-3. Lastly, this.
diff --git a/docs/source/examples.rst b/docs/source/examples.rst
deleted file mode 100644
index 7cdd42fe9368f68ba23a1e99bf770ef7d997c2b8..0000000000000000000000000000000000000000
--- a/docs/source/examples.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-.. _examples:
-
-===========================
-Examples
-===========================
-
-Eventually we would like to have several TOPFARM examples here to demonstrate
-how you can use the code.
diff --git a/docs/source/examples/example_1_constrained_layout_optimization.rst b/docs/source/examples/example_1_constrained_layout_optimization.rst
new file mode 100644
index 0000000000000000000000000000000000000000..149f9e11802c7c59fb7c7b52613bbd0d955c8843
--- /dev/null
+++ b/docs/source/examples/example_1_constrained_layout_optimization.rst
@@ -0,0 +1,36 @@
+.. Example 1
+
+Example 1: Constrained Layout Optimization
+===========================================
+
+This example demonstrates the optimization of a wind turbine layout that is
+subject to boundary constraints.
+
+Specifications
+--------------
+
+- The cost function is a dummy function that penalizes the turbines when they
+  are far away from pre-specified, desired positions.  
+- There is a boundary beyond which the turbines cannot go.  
+- The turbines cannot be closer than 2D.
+
+Results
+-------
+
+The optimization results are visualized in the figure below. The turbines'
+trajectories during the optimizations are shown by the colored lines.
+
+- All turbines that begin outside the boundary immediately jump inside the
+  boundary.  
+- Turbines 1 and 3 rotate around each other as they try to reach their
+  specified final locations but stay at least 2D away from each other.
+- Turbine 2 remains on the boundary but tries to minimize its distance to
+  its specified final location.  
+- Turbine 4 converges to its specified location.
+
+.. figure:: /../../examples/example_1_constrained_layout_optimization.png
+
+Code
+----
+
+.. literalinclude:: /../../examples/example_1_constrained_layout_optimization.py
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 6f30b010d65e79bd8c7a1b520d5a9f466957703f..7757c90e4a5f4f9838493c86e5294421d2aa4080 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -10,13 +10,9 @@ Welcome to TOPFARM, the wind-farm optimizer
     :maxdepth: 2
 
     installation
-    examples
 
+.. toctree::
+    :caption: Examples
+    :maxdepth: 2
 
-
-Indices and tables
-==================
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
+    examples/example_1_constrained_layout_optimization
diff --git a/examples/example_1_constrained_layout_optimization.py b/examples/example_1_constrained_layout_optimization.py
new file mode 100644
index 0000000000000000000000000000000000000000..99c761d6a65491336a977492b072fcdb54722bbd
--- /dev/null
+++ b/examples/example_1_constrained_layout_optimization.py
@@ -0,0 +1,74 @@
+"""Example: optimizing a layout with constraints
+
+This example uses a dummy cost function to optimize a simple wind turbine
+layout that is subject to constraints. The optimization pushes the wind turbine
+locations to specified locations in the farm.
+"""
+import os
+
+from matplotlib.patches import Polygon
+import matplotlib.pyplot as plt
+import numpy as np
+
+from topfarm import TopFarm
+from topfarm.cost_models.dummy import DummyCost
+
+
+# ------------------------ INPUTS ------------------------
+
+# define the conditions for the wind farm
+boundary = [(0, 0), (6, 0), (6, -10), (0, -10)]  # turbine boundaries
+initial = np.array([[6, 0], [6, -8], [1, 1], [-1, -8]])  # initial turbine pos
+desired = np.array([[3, -3], [7, -7], [4, -3], [3, -7]])  # desired turbine pos
+optimal = np.array([[2.5, -3], [6, -7], [4.5, -3], [3, -7]])  # optimal layout
+min_spacing = 2  # min distance between turbines
+
+# ------------------------ OPTIMIZATION ------------------------
+
+# create the wind farm and run the optimization
+tf = TopFarm(initial, DummyCost(desired, ['turbineX', 'turbineY']),
+             min_spacing, boundary=boundary, record_id=None)
+cost, state, recorder = tf.optimize()
+
+# get the positions tried during optimization from the recorder
+rec_x, rec_y = recorder.get('turbineX'), recorder.get('turbineY')
+
+# get the final, optimal positions
+optimized = tf.turbine_positions
+
+# ------------------------ PLOT (if possible) ------------------------
+
+try:
+
+    # initialize the figure and axes
+    fig = plt.figure(1, figsize=(7, 5))
+    plt.clf()
+    ax = plt.axes()
+
+    # plot the boundary and desired locations
+    ax.add_patch(Polygon(boundary, closed=True, fill=False,
+                         label='Boundary'))  # boundary
+    plt.plot(desired[:, 0], desired[:, 1], 'ok', mfc='None', ms=10,
+             label='Desired')  # desired positions
+
+    # plot the history of each turbine
+    for i_turb in range(rec_x.shape[1]):
+        l, = plt.plot(rec_x[0, i_turb], rec_y[0, i_turb],
+                      'x', ms=8, label=f'Turbine {i_turb+1}')  # initial
+        plt.plot(rec_x[:, i_turb], rec_y[:, i_turb],
+                 c=l.get_color())  # tested values
+        plt.plot(rec_x[-1, i_turb], rec_y[-1, i_turb],
+                 'o', ms=8, c=l.get_color())  # final
+
+    # make a few adjustments to the plot
+    ax.autoscale_view()  # autoscale the boundary
+    plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3,
+               ncol=4, mode='expand', borderaxespad=0.)  # add a legend
+    plt.tight_layout()  # zoom the plot in
+    plt.axis('off')  # remove the axis
+
+    # save the png
+    fig.savefig(os.path.basename(__file__).replace('.py', '.png'))
+
+except RuntimeError:
+    pass
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..cdc9c412e7180d995e18cbde71ee3cb400e1a316
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,3 @@
+# add example_*.py files to those that pytest should test
+[tool:pytest]
+python_files = test_*.py *_test.py testing/*/*.py example_*.py
\ No newline at end of file