diff --git a/bob/bio/face/annotator/Base.py b/bob/bio/face/annotator/Base.py
index e925a821ebe463c9376c3587a840c9b930e522a1..02c9220188d135deb8e1517ed80557c88dc7b8eb 100644
--- a/bob/bio/face/annotator/Base.py
+++ b/bob/bio/face/annotator/Base.py
@@ -1,8 +1,8 @@
-from bob.bio.base.annotator import Annotator
-from bob.bio.face.preprocessor import FaceCrop  # import for documentation
+import bob.bio.base.annotator
+import bob.bio.face.preprocessor  # import for documentation
 
 
-class Base(Annotator):
+class Base(bob.bio.base.annotator.Annotator):
     """Base class for all face annotators"""
 
     def __init__(self, **kwargs):
@@ -12,7 +12,8 @@ class Base(Annotator):
         """Annotates an image and returns annotations in a dictionary. All
         annotator should return at least the ``topleft`` and ``bottomright``
         coordinates. Some currently known annotation points such as ``reye``
-        and ``leye`` are formalized in :any:`FaceCrop`.
+        and ``leye`` are formalized in
+        :any:`bob.bio.face.preprocessor.FaceCrop`.
 
         Parameters
         ----------
diff --git a/bob/bio/face/annotator/__init__.py b/bob/bio/face/annotator/__init__.py
index e4969daca3857c6f664d7d27ab64ab539d63314e..8c556a0e3504a280e8432fc51bb2feecf286b2d9 100644
--- a/bob/bio/face/annotator/__init__.py
+++ b/bob/bio/face/annotator/__init__.py
@@ -47,7 +47,7 @@ def min_face_size_validator(annotations, min_face_size=(32, 32)):
 
 # These imports should be here to avoid circular dependencies
 from .Base import Base
-from .bobipfacedetect import BobIpFacedetect, BoundingBoxToEyes
+from .bobipfacedetect import BobIpFacedetect
 from .bobipflandmark import BobIpFlandmark
 from .bobipdlib import BobIpDlib
 from .bobipmtcnn import BobIpMTCNN
@@ -75,7 +75,6 @@ def __appropriate__(*args):
 __appropriate__(
     Base,
     BobIpFacedetect,
-    BoundingBoxToEyes,
     BobIpFlandmark,
     BobIpDlib,
     BobIpMTCNN,
diff --git a/bob/bio/face/annotator/bobipfacedetect.py b/bob/bio/face/annotator/bobipfacedetect.py
index afae049212c06cb8314054bda5337f0e8978acf5..a12af8a119ad41f45ceaaa9eeab07cd9d90ad1c0 100644
--- a/bob/bio/face/annotator/bobipfacedetect.py
+++ b/bob/bio/face/annotator/bobipfacedetect.py
@@ -1,30 +1,56 @@
 import math
-from bob.io.base import HDF5File
-from bob.ip.color import rgb_to_gray
-from bob.ip.facedetect import (
-    detect_single_face, Sampler, default_cascade, Cascade,
-    bounding_box_from_annotation, expected_eye_positions)
+import bob.io.base
+import bob.ip.color
+import bob.ip.facedetect
 from . import Base, bounding_box_to_annotations
 
 
 class BobIpFacedetect(Base):
     """Annotator using bob.ip.facedetect
     Provides topleft and bottomright annoations.
+
+    Parameters
+    ----------
+    cascade : :any:`bob.ip.facedetect.Cascade`
+        The file name, where a face detector cascade can be found. If ``None``,
+        the default cascade for frontal faces
+        :any:`bob.ip.facedetect.default_cascade` is used.
+
+    detection_overlap : float
+        See :any:`bob.ip.facedetect.detect_single_face`.
+
+    distance : int
+        See the Sampling section in the
+        :ref:`Users Guide of bob.ip.facedetect <bob.ip.facedetect>`.
+
+    scale_base : float
+        See the Sampling section in the
+        :ref:`Users Guide of bob.ip.facedetect <bob.ip.facedetect>`.
+
+    lowest_scale : float
+        See the Sampling section in the
+        :ref:`Users Guide of bob.ip.facedetect <bob.ip.facedetect>`.
+
+    eye_estimate : bool
+        If ``True``, expected eye locations are added to the annotations.
     """
 
     def __init__(self, cascade=None,
                  detection_overlap=0.2, distance=2,
                  scale_base=math.pow(2., -1. / 16.), lowest_scale=0.125,
+                 eye_estimate=False,
                  **kwargs):
         super(BobIpFacedetect, self).__init__(**kwargs)
-        self.sampler = Sampler(
+        self.sampler = bob.ip.facedetect.Sampler(
             scale_factor=scale_base, lowest_scale=lowest_scale,
             distance=distance)
         if cascade is None:
-            self.cascade = default_cascade()
+            self.cascade = bob.ip.facedetect.default_cascade()
         else:
-            self.cascade = Cascade(HDF5File(cascade))
+            self.cascade = bob.ip.facedetect.Cascade(
+                bob.io.base.HDF5File(cascade))
         self.detection_overlap = detection_overlap
+        self.eye_estimate = eye_estimate
 
     def annotate(self, image, **kwargs):
         """Return topleft and bottomright and expected eye positions
@@ -43,47 +69,13 @@ class BobIpFacedetect(Base):
             quality, leye, reye.
         """
         if image.ndim == 3:
-            image = rgb_to_gray(image)
-        bounding_box, quality = detect_single_face(
+            image = bob.ip.color.rgb_to_gray(image)
+        bbx, quality = bob.ip.facedetect.detect_single_face(
             image, self.cascade, self.sampler, self.detection_overlap)
-        landmarks = bounding_box_to_annotations(bounding_box)
-        landmarks['quality'] = quality
-        return landmarks
-
-
-class BoundingBoxToEyes(Base):
-    """Converts bounding box annotations to eye locations. The bounding box's
-    annotations is expected to have come from :any:`BobIpFacedetect`.
-
-    Example usage:
-
-    .. doctest::
-
-        >>> from bob.bio.base.annotator import FailSafe
-        >>> from bob.bio.face.annotator import (
-        ...     BobIpFacedetect, BoundingBoxToEyes)
-        >>> annotator = FailSafe(
-        ...     [BobIpFacedetect(), BoundingBoxToEyes()],
-        ...     required_keys=('reye', 'leye'))
-    """
-
-    def annotate(self, image, annotations, **kwargs):
-        """Converts bounding boxes of bob.ip.facedetect to eye locations.
 
-        Parameters
-        ----------
-        image : numpy.array
-            Ignored.
-        annotations : dict
-            The annotations that are given by :any:`BobIpFacedetect`.
-        **kwargs
-            Ignored.
+        landmarks = bounding_box_to_annotations(bbx)
+        landmarks['quality'] = quality
+        if self.eye_estimate:
+            landmarks.update(bob.ip.facedetect.expected_eye_positions(bbx))
 
-        Returns
-        -------
-        dict
-            The annotations with reye and leye locations added.
-        """
-        bbx = bounding_box_from_annotation(source='direct', **annotations)
-        annotations.update(expected_eye_positions(bbx))
-        return annotations
+        return landmarks
diff --git a/bob/bio/face/config/annotator/facedetect_eye_estimate.py b/bob/bio/face/config/annotator/facedetect_eye_estimate.py
index a42e19116a087a0fbec07d5b9e5b214b06b48b87..56834937dbe6001c0f1a98bc744469cac538b22a 100644
--- a/bob/bio/face/config/annotator/facedetect_eye_estimate.py
+++ b/bob/bio/face/config/annotator/facedetect_eye_estimate.py
@@ -1,6 +1,3 @@
-from bob.bio.base.annotator import FailSafe
-from bob.bio.face.annotator import BobIpFacedetect, BoundingBoxToEyes
+from bob.bio.face.annotator import BobIpFacedetect
 
-annotator = FailSafe(
-    [BobIpFacedetect(), BoundingBoxToEyes()],
-    required_keys=('reye', 'leye'))
+annotator = BobIpFacedetect(eye_estimate=True)
diff --git a/bob/bio/face/test/test_annotators.py b/bob/bio/face/test/test_annotators.py
index e35c0a4a199dee80295b8729b3d8eb57bbf7ac5e..7ba3082087ccdd3951f2bb9b075f6f99c5d79797 100644
--- a/bob/bio/face/test/test_annotators.py
+++ b/bob/bio/face/test/test_annotators.py
@@ -2,7 +2,7 @@ import bob.io.base
 import bob.io.base.test_utils
 import bob.io.image
 from bob.bio.face.annotator import (
-    BobIpFacedetect, BoundingBoxToEyes, BobIpFlandmark,
+    BobIpFacedetect, BobIpFlandmark,
     min_face_size_validator)
 from bob.bio.base.annotator import FailSafe
 import numpy
@@ -18,19 +18,12 @@ def _assert_bob_ip_facedetect(annot):
 
 
 def test_bob_ip_facedetect():
-    from bob.bio.face.annotator.bobipfacedetect import BobIpFacedetect
     annot = BobIpFacedetect()(face_image)
     _assert_bob_ip_facedetect(annot)
 
 
 def test_bob_ip_facedetect_eyes():
-    annotator = FailSafe(
-        [BobIpFacedetect(), BoundingBoxToEyes()],
-        required_keys=('reye', 'leye'),
-    )
-
-    annot = annotator(face_image)
-
+    annot = BobIpFacedetect(eye_estimate=True)(face_image)
     _assert_bob_ip_facedetect(annot)
     assert [int(x) for x in annot['reye']] == [175, 128], annot
     assert [int(x) for x in annot['leye']] == [175, 221], annot
diff --git a/doc/implemented.rst b/doc/implemented.rst
index c00192097f092b0fee8a7ba7fcd96be6e5108bcf..5db52a00cba27b61fae93b6465afba704e4091d4 100644
--- a/doc/implemented.rst
+++ b/doc/implemented.rst
@@ -34,7 +34,6 @@ Face Image Annotators
 .. autosummary::
    bob.bio.face.annotator.Base
    bob.bio.face.annotator.BobIpFacedetect
-   bob.bio.face.annotator.BoundingBoxToEyes
    bob.bio.face.annotator.BobIpFlandmark
    bob.bio.face.annotator.BobIpDlib
    bob.bio.face.annotator.BobIpMTCNN