diff --git a/Code/Seg/BSTools/bsdetectionwidget.cpp b/Code/Seg/BSTools/bsdetectionwidget.cpp
index 6ac098dc14c5d9ebc97aafb81962f285f59db286..700674c89e4c8ca2be0c9757f0e204b355829303 100755
--- a/Code/Seg/BSTools/bsdetectionwidget.cpp
+++ b/Code/Seg/BSTools/bsdetectionwidget.cpp
@@ -28,6 +28,8 @@ BSDetectionWidget::BSDetectionWidget (QWidget *parent)
   grabKeyboard ();
   udef = false;
   nodrag = true;
+  nbdettrials = 0;
+  nbmaxdettrials = 0;
 
   // Initializes the gradient map and the auxiliary views
   gMap = NULL;
@@ -41,15 +43,14 @@ BSDetectionWidget::BSDetectionWidget (QWidget *parent)
   verbose = false;
   background = BACK_IMAGE;
   bsBoundsVisible = false;
-  exam = -1;
 
   // Sets display parameters
   selectionColor = Qt::red;
-  bsColor = Qt::yellow;
-  bsHighColor = Qt::blue;
+  bsColor = Qt::blue;
+  bsHighColor = Qt::yellow;
   bsPointsVisible = true;
-  boundColor = Qt::magenta;
-  boundHighColor = Qt::green;
+  boundColor = Qt::green;
+  boundHighColor = Qt::magenta;
 }
 
 
@@ -284,7 +285,6 @@ void BSDetectionWidget::switchIdetAnalyzer ()
   {
     idetview = new BSIdetView (&detector);
     idetview->setImage (&loadedImage, gMap);
-    if (! p1.equals (p2)) idetview->buildScans (p1, p2);
     idetview->show ();
   }
 }
@@ -294,6 +294,7 @@ void BSDetectionWidget::mousePressEvent (QMouseEvent *event)
 {
   oldp1.set (p1);
   oldp2.set (p2);
+  oldudef = udef;
   p1 = Pt2i (event->pos().x (), height - 1 - event->pos().y());
   if (p1.manhattan (p2) < 10) p1.set (oldp1);
   else if (p1.manhattan (oldp1) < 10) p1.set (p2);
@@ -308,13 +309,21 @@ void BSDetectionWidget::mouseReleaseEvent (QMouseEvent *event)
   {
     p1.set (oldp1);
     p2.set (oldp2);
+    udef = oldudef;
   }
   else
   {
     alternate = 0;
     cerr << "p1 defined: " << p1.x () << " " << p1.y () << endl;
     cerr << "p2 defined: " << p2.x () << " " << p2.y () << endl;
+    detector.setMaxTrials (0);
     extract ();
+    nbdettrials = detector.countOfTrials ();
+    nbmaxdettrials = 0;
+    if (detector.isMultiSelection ())
+      cout << detector.getBlurredSegments().size ()
+           << " blurred segments detected on "
+           << nbdettrials << " essais " << endl;
   }
 }
 
@@ -331,6 +340,7 @@ void BSDetectionWidget::mouseMoveEvent (QMouseEvent *event)
     nodrag = false;
     extract ();
     nodrag = true;
+    detector.setMaxTrials (0);
   }
 }
 
@@ -484,9 +494,15 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event)
       else
       {
         // Runs an automatic detection
+cout << "AUTO" << endl;
         udef = false;
-        exam = -1;
+        detector.setMaxTrials (-1);
         extract ();
+        nbdettrials = detector.countOfTrials ();
+        nbmaxdettrials = 0;
+        cout << detector.getBlurredSegments().size ()
+             << " blurred segments detected on "
+             << nbdettrials << " essais " << endl;
       }
       break;
 
@@ -504,8 +520,12 @@ void BSDetectionWidget::keyPressEvent (QKeyEvent *event)
         // Highlights the next segment in a multi-detection
         if (! detector.getBlurredSegments().empty ())
         {
-          displayNext (event->modifiers () & Qt::ShiftModifier ? -1 : 1);
-          cout << "Selection du segment " << exam << endl;
+          nbmaxdettrials += (event->modifiers () & Qt::ShiftModifier ? -1 : 1);
+          if (nbmaxdettrials < 0) nbmaxdettrials = nbdettrials;
+          else if (nbmaxdettrials > nbdettrials) nbmaxdettrials = 0;
+          detector.setMaxTrials (nbmaxdettrials);
+          cout << "Selection du segment " << nbmaxdettrials << endl;
+          extract ();
         }
       }
       break;
@@ -841,10 +861,13 @@ void BSDetectionWidget::displayDetectionResult ()
   vector<BlurredSegment *> bss = detector.getBlurredSegments ();
   if (! bss.empty ())
   {
-    int index = 0;
     vector<BlurredSegment *>::const_iterator it = bss.begin ();
     while (it != bss.end ())
-      drawBlurredSegment (painter, *it++, index++ == exam);
+    {
+      drawBlurredSegment (painter, *it, nbmaxdettrials == 0 ||
+                          (*it == bss.back () && detector.isLastTrialOk ()));
+      it++;
+    }
   }
   else
     drawBlurredSegment (painter, detector.getBlurredSegment ());
@@ -854,11 +877,7 @@ void BSDetectionWidget::displayDetectionResult ()
   // Update auxiliary view if not dragging
   if (nodrag)
   {
-    if (idetview != NULL)
-    {
-      idetview->buildScans (p1, p2);
-      idetview->scene()->update ();
-    }
+    if (idetview != NULL) idetview->scene()->update ();
     if (profileview != NULL)
     {
       profileview->buildScans (p1, p2);
@@ -867,7 +886,6 @@ void BSDetectionWidget::displayDetectionResult ()
     if (accuview != NULL) accuview->scene()->update ();
     if (strucview != NULL)
     {
-      strucview->setExamined (-1);
       strucview->scene()->update ();
       strucview->repaint ();
     }
@@ -876,18 +894,6 @@ void BSDetectionWidget::displayDetectionResult ()
 }
 
 
-void BSDetectionWidget::displayNext (int dir)
-{
-  int size = (int) (detector.getBlurredSegments ().size ());
-  if (size != 0)
-  {
-    exam = (exam + dir) % size;
-    if (strucview != NULL) strucview->setExamined (exam);
-    displayDetectionResult ();
-  }
-}
-
-
 void BSDetectionWidget::displaySavedSegments ()
 {
   if (background == BACK_BLACK) augmentedImage.fill (qRgb (0, 0, 0));
@@ -986,15 +992,8 @@ void BSDetectionWidget::writeDetectionStatus ()
 
 void BSDetectionWidget::extract ()
 {
-  if (! udef)
-  {
-    detector.detectAll ();
-    cout << detector.getBlurredSegments().size ()
-         << " blurred segments detected" << endl;
-  }
-  else
+  if (udef)
   {
-    exam = -1;
     if (p1.equals (p2))
     {
       displayBackground ();
@@ -1002,6 +1001,7 @@ void BSDetectionWidget::extract ()
     }
     detector.detectSelection (p1, p2);
   }
+  else detector.detectAll ();
   displayDetectionResult ();
 }
 
diff --git a/Code/Seg/BSTools/bsdetectionwidget.h b/Code/Seg/BSTools/bsdetectionwidget.h
index 36c299460e57261aff545c8800a293cdb06c0a6e..a961972c142787e331b412c49e90271c5bb4e071 100755
--- a/Code/Seg/BSTools/bsdetectionwidget.h
+++ b/Code/Seg/BSTools/bsdetectionwidget.h
@@ -204,10 +204,14 @@ private:
   bool nodrag;
   /** Flag indicating if the detection is user defined. */
   bool udef;
-  /** Index of the examined blurred segment in a multi-selection. */
-  int exam;
+  /** Saved user definition flag. */
+  bool oldudef;
   /** Activation of alternate comparative tests (F8). */
   int alternate;
+  /** Count of trials in a multi_detection. */
+  int nbdettrials;
+  /** Maximum number of trials in a multi_detection. */
+  int nbmaxdettrials;
 
   /** Color of user selections. */
   QColor selectionColor;
@@ -309,7 +313,7 @@ private:
    * @param high Flag indicated whether the blurred segment is highlighted.
    */
   void drawBlurredSegment (QPainter &painter,
-                           BlurredSegment *bs, bool high = false);
+                           BlurredSegment *bs, bool high = true);
 
   /**
    * \brief Displays the window background (no detection).
@@ -326,12 +330,6 @@ private:
    */
   void displayDetectionResult ();
 
-  /**
-   * \brief Highlights the next blurred segment in multi-selection mode.
-   * @param dir Increment in the multi-selection.
-   */
-  void displayNext (int dir);
-
   /**
    * \brief Displays the saved blurred segments.
    */
diff --git a/Code/Seg/BSTools/bsidetitem.cpp b/Code/Seg/BSTools/bsidetitem.cpp
index 16a3551021bd18542afa1f5e8fb009763f5c00cf..77f7ba541990e52094cb4ab3640e21627ae91689 100755
--- a/Code/Seg/BSTools/bsidetitem.cpp
+++ b/Code/Seg/BSTools/bsidetitem.cpp
@@ -47,7 +47,11 @@ void BSIdetItem::paint (QPainter *painter,
   Q_UNUSED (option);
   Q_UNUSED (widget);
 
-  paintStripes (painter);
+  if (det->getBlurredSegments().empty () || det->getMaxTrials () > 0)
+  {
+    buildScans ();
+    paintStripes (painter);
+  }
 }
 
 
@@ -61,13 +65,20 @@ void BSIdetItem::setImage (QImage *image, VMap *idata)
 }
 
 
-void BSIdetItem::buildScans (Pt2i p1, Pt2i p2)
+void BSIdetItem::buildScans ()
 {
-  if (ds != NULL) delete ds;
+  if (ds != NULL)
+  {
+    delete ds;
+    ds = NULL;
+  }
 
   // Updates the central scan end points for parallel display
-  this->pt1 = p1;
-  this->pt2 = p2;
+  Pt2i ptc;
+  int scanw = 0;
+  int step = (det->isPreliminary () ?
+              BSDetector::STEP_PRELIM : BSDetector::STEP_INITIAL);
+  det->getScanInput (step, pt1, pt2, scanw, ptc);
 
   // Resets the idets
   rightscan.clear ();
@@ -76,11 +87,13 @@ void BSIdetItem::buildScans (Pt2i p1, Pt2i p2)
   offy = 0;
 
   // Gets a scan iterator
-  ds = scanp.getScanner (p1, p2);
+  if (scanw)
+    ds = scanp.getScanner (ptc, pt1.vectorTo (pt2), scanw, false);
+  else ds = scanp.getScanner (pt1, pt2);
 
   // Extracts the left scan (with central one)
   vector<Pt2i> pix;
-  if (ds->first (pix) < MIN_SCAN) { delete ds; return;}
+  if (ds->first (pix) < MIN_SCAN) { delete ds; ds = NULL; return;}
   leftscan.push_back (pix);
   int sw = pix.size ();
 
@@ -202,7 +215,9 @@ if (pt1.equals (pt2)) return;
     }
   }
 
-  BlurredSegment *bs = det->getBlurredSegment (BSDetector::STEP_INITIAL);
+  BlurredSegment *bs = det->getBlurredSegment (
+    det->isPreliminary () ? BSDetector::STEP_PRELIM
+                          : BSDetector::STEP_INITIAL);
   if (bs != NULL)
   {
 //    const vector<Pt2i> *pts = bs->getLeftPoints ();
diff --git a/Code/Seg/BSTools/bsidetitem.h b/Code/Seg/BSTools/bsidetitem.h
index b8cf42db0dc5d015cd834e9e38a3d5724281160c..bc594acbd4eb8c6665990d92e53e63bce8291da2 100755
--- a/Code/Seg/BSTools/bsidetitem.h
+++ b/Code/Seg/BSTools/bsidetitem.h
@@ -30,12 +30,6 @@ public:
    */
   void setImage (QImage *image, VMap *idata);
 
-  /**
-   * \brief Sets the image scan area from an initial scan.
-   * The initial scan is a straight segment from p1 to p2.
-   */
-  void buildScans (Pt2i p1, Pt2i p2);
-
   /**
    * \brief Returns the widget size.
    * Nominally the image size.
@@ -143,6 +137,11 @@ private:
    */
   void paintStripes (QPainter *painter);
 
+  /**
+   * \brief Sets the image scan area from the detection initial scan.
+   */
+  void buildScans ();
+
 };
 
 #endif
diff --git a/Code/Seg/BSTools/bsidetview.cpp b/Code/Seg/BSTools/bsidetview.cpp
index d38c78b16365bfdfdc2fbd2c45389ffd9cdd14bf..dc6cfcc116fd7dd005af62a2930d91efd8cf0f0e 100755
--- a/Code/Seg/BSTools/bsidetview.cpp
+++ b/Code/Seg/BSTools/bsidetview.cpp
@@ -42,12 +42,6 @@ void BSIdetView::setImage (QImage *image, VMap *idata)
 }
 
 
-void BSIdetView::buildScans (Pt2i p1, Pt2i p2)
-{
-  idet->buildScans (p1, p2);
-}
-
-
 bool BSIdetView::processKeyEvent (QKeyEvent *event)
 {
   switch (event->key ())
diff --git a/Code/Seg/BSTools/bsstructureitem.cpp b/Code/Seg/BSTools/bsstructureitem.cpp
index c52e75f4aedd3ac91ecdbd5acc248d9fa530f5a6..77bc856b50688abcfc227c707e4fc6e218a61063 100755
--- a/Code/Seg/BSTools/bsstructureitem.cpp
+++ b/Code/Seg/BSTools/bsstructureitem.cpp
@@ -12,8 +12,10 @@ const int BSStructureItem::DISPLAY_INITIAL_BLURRED_SEGMENT = 4;
 const int BSStructureItem::DISPLAY_INITIAL_CONNECTED_COMPONENTS = 5;
 const int BSStructureItem::DISPLAY_INITIAL_SCANS_AND_FILTER = 6;
 const int BSStructureItem::DISPLAY_PRELIM_BLURRED_SEGMENT = 7;
+const int BSStructureItem::DISPLAY_PRELIM_CONNECTED_COMPONENTS = 8;
+const int BSStructureItem::DISPLAY_PRELIM_SCANS_AND_FILTER = 9;
 const int BSStructureItem::DISPLAY_MIN = DISPLAY_FINAL_BLURRED_SEGMENT;
-const int BSStructureItem::DISPLAY_MAX = DISPLAY_PRELIM_BLURRED_SEGMENT;
+const int BSStructureItem::DISPLAY_MAX = DISPLAY_PRELIM_SCANS_AND_FILTER;
 
 const int BSStructureItem::DEFAULT_PEN_WIDTH = 1;
 const int BSStructureItem::LEFT_MARGIN = 16;
@@ -107,16 +109,16 @@ void BSStructureItem::paint (QPainter *painter,
     paintScansAndFilter (painter, BSDetector::STEP_INITIAL);
   else if (displayItem == DISPLAY_PRELIM_BLURRED_SEGMENT)
     paintBlurredSegment (painter, BSDetector::STEP_PRELIM);
+  else if (displayItem == DISPLAY_PRELIM_CONNECTED_COMPONENTS)
+    paintConnectedComponents (painter, BSDetector::STEP_PRELIM);
+  else if (displayItem == DISPLAY_PRELIM_SCANS_AND_FILTER)
+    paintScansAndFilter (painter, BSDetector::STEP_PRELIM);
 }
 
 
 void BSStructureItem::paintBlurredSegment (QPainter *painter, int step)
 {
-  BlurredSegment *bs = NULL;
-  vector<BlurredSegment *> mbs = det->getBlurredSegments (step);
-  if (mbs.empty ()) bs = det->getBlurredSegment (step);
-  else if (exam != -1) bs = mbs[exam];
-    
+  BlurredSegment *bs = det->getBlurredSegment (step);
   if (bs != NULL)
   {
     DigitalStraightSegment *dss = bs->getSegment ();
@@ -163,11 +165,7 @@ void BSStructureItem::paintBlurredSegment (QPainter *painter, int step)
 
 void BSStructureItem::paintConnectedComponents (QPainter *painter, int step)
 {
-  BlurredSegment *bs = NULL;
-  vector<BlurredSegment *> mbs = det->getBlurredSegments (step);
-  if (mbs.empty ()) bs = det->getBlurredSegment (step);
-  else if (exam != -1) bs = mbs[exam];
-    
+  BlurredSegment *bs = det->getBlurredSegment (step);
   if (bs != NULL)
   {
     QColor cols[] = {Qt::blue, Qt::red, Qt::green};
@@ -185,9 +183,9 @@ void BSStructureItem::paintConnectedComponents (QPainter *painter, int step)
   if (verbose)
   {
     initText (painter);
-    int ccs = det->getConnectedComponentMinSize ();
     if (bs != NULL)
     {
+      int ccs = det->getConnectedComponentMinSize ();
       int bsccp = bs->countOfConnectedPoints (ccs);
       int bssize = bs->getAllPoints().size ();
       bool ccon = (step == BSDetector::STEP_FINAL
@@ -214,44 +212,76 @@ void BSStructureItem::paintConnectedComponents (QPainter *painter, int step)
 
 void BSStructureItem::paintScansAndFilter (QPainter *painter, int step)
 {
-  if (! (det->getBlurredSegments(step).empty ())) return;
-    
-  if (det->scanRecordOn (step))
+  vector <vector <Pt2i> > scanLines;
+  if (step == BSDetector::STEP_FINAL) scanLines = det->getFinalScans ();
+  else
   {
-    if (displayScanLines)
+    if (step == BSDetector::STEP_PRELIM && ! det->isPreliminary ()) return;
+    Pt2i pt1, pt2, ptc (-1, -1);
+    int swidth = 0;
+    det->getScanInput (step, pt1, pt2, swidth, ptc);
+    ScannerProvider sp;
+    sp.setSize (w, h);
+    DirectionalScanner *ds = NULL;
+    if (swidth)
+      ds = sp.getScanner (ptc, pt1.vectorTo (pt2), swidth, false);
+    else ds = sp.getScanner (pt1, pt2);
+    vector<Pt2i> pix;
+    ds->first (pix);
+    scanLines.push_back (pix);
+    bool on = true;
+    while (on)
     {
-      QColor col[] = {Qt::blue, Qt::red, Qt::green};
-      int i = 0;
-      vector < vector <Pt2i> > scns = det->getScans (step);
-      if (scns.size () > 0)
+      if (ds->nextOnRight (pix) < 1) on = false;
+      else scanLines.push_back (pix);
+    }
+    on = true;
+    while (on)
+    {
+      if (ds->nextOnLeft (pix) < 1) on = false;
+      else scanLines.push_back (pix);
+    }
+  }
+  if (displayScanLines)
+  {
+    QColor col[] = {Qt::blue, Qt::red, Qt::green};
+    int i = 0;
+    if (! scanLines.empty ())
+    {
+      vector <vector <Pt2i> >::const_iterator it = scanLines.begin ();
+      paintPixel (painter, it->front (), col[2]);
+      paintPixel (painter, it->back (), col[2]);
+      it++;  // Displays only the bounds of the central scan
+      while (it != scanLines.end ())
       {
-        vector <vector <Pt2i> >::const_iterator it = scns.begin ();
-        paintPixel (painter, it->front (), col[2]);
-        paintPixel (painter, it->back (), col[2]);
-        it++;  // Displays only the bounds of the central scan
-        while (it != scns.end ())
-        {
-          paintPixels (painter, *it, col[i]);
-          it++;
-          if (++i == 3) i = 0;
-        }
+        paintPixels (painter, *it, col[i]);
+        it++;
+        if (++i == 3) i = 0;
       }
     }
-    else
+  }
+  else
+  {
+    // Displays scan bounds
+    if (! scanLines.empty ())
     {
-      // Displays scan bounds
-      paintPixels (painter, det->getScanBound1 (step), Qt::blue);
-      paintPixels (painter, det->getScanBound2 (step), Qt::blue);
-
-      // Displays filter
-      if (det->isFiltering (step))
+      vector <vector <Pt2i> >::const_iterator it = scanLines.begin ();
+      while (it != scanLines.end ())
       {
-        paintPixels (painter, det->getAccepted (step), Qt::green);
-        paintPixels (painter, det->getRejected (step), Qt::red);
-        BlurredSegment *bs = det->getBlurredSegment (step);
-        if (bs != NULL) paintPixels (painter, bs->getStartPt (), Qt::yellow);
+        paintPixel (painter, it->front (), Qt::blue);
+        paintPixel (painter, it->back (), Qt::blue);
+        it ++;
       }
     }
+
+    // Displays filter output
+    if (det->isFiltering (step))
+    {
+      paintPixels (painter, det->getAccepted (step), Qt::green);
+      paintPixels (painter, det->getRejected (step), Qt::red);
+      BlurredSegment *bs = det->getBlurredSegment (step);
+      if (bs != NULL) paintPixels (painter, bs->getStartPt (), Qt::yellow);
+    }
   }
 
   if (verbose)
@@ -272,10 +302,7 @@ void BSStructureItem::toggleDisplay (bool next)
   displayItem += (next ? 1 : -1);
   if (displayItem > DISPLAY_MAX) displayItem = DISPLAY_MIN;
   else if (displayItem < DISPLAY_MIN) displayItem = DISPLAY_MAX;
-  det->setScanRecord (BSDetector::STEP_FINAL,
-                      displayItem == DISPLAY_FINAL_SCANS_AND_FILTER);
-  det->setScanRecord (BSDetector::STEP_INITIAL,
-                      displayItem == DISPLAY_INITIAL_SCANS_AND_FILTER);
+  det->setFinalScansRecord (displayItem == DISPLAY_FINAL_SCANS_AND_FILTER);
 }
 
 
diff --git a/Code/Seg/BSTools/bsstructureitem.h b/Code/Seg/BSTools/bsstructureitem.h
index deacfb3358296045acbfae2824ce00624712f0a5..f2095debd8abe4c394c994412297c1d21aacf825 100755
--- a/Code/Seg/BSTools/bsstructureitem.h
+++ b/Code/Seg/BSTools/bsstructureitem.h
@@ -70,11 +70,6 @@ public:
    */
   inline void switchScanDisplay () { displayScanLines = ! displayScanLines; }
 
-  /**
-   * Sets the examined segment from a multi-selection.
-   */
-  inline void setExamined (int index) { exam = index; }
-
   /**
    * \brief Returns the displayed information title.
    */
@@ -93,6 +88,10 @@ public:
       return ("Initial scans and filter");
     else if (displayItem == DISPLAY_PRELIM_BLURRED_SEGMENT)
       return ("Preliminary blurred segment");
+    else if (displayItem == DISPLAY_PRELIM_CONNECTED_COMPONENTS)
+      return ("Preliminary connected components");
+    else if (displayItem == DISPLAY_PRELIM_SCANS_AND_FILTER)
+      return ("Preliminary scans and filter");
     else return ("No info");
   }
 
@@ -124,6 +123,10 @@ private:
   static const int DISPLAY_INITIAL_SCANS_AND_FILTER;
   /** Available information : preliminary blurred segment points and bounds. */
   static const int DISPLAY_PRELIM_BLURRED_SEGMENT;
+  /** Available information : preliminary connected components. */
+  static const int DISPLAY_PRELIM_CONNECTED_COMPONENTS;
+  /** Available information : preliminary scans and filter output. */
+  static const int DISPLAY_PRELIM_SCANS_AND_FILTER;
   /** Number of the first information. */
   static const int DISPLAY_MIN;
   /** Number of the last information. */
@@ -161,8 +164,6 @@ private:
   QPen infoPen;
   /** Information text vertical offset. */
   int textOffset;
-  /** Index of the examined segment in the multi-selection. */
-  int exam;
 
 
   /**
diff --git a/Code/Seg/BSTools/bsstructureview.cpp b/Code/Seg/BSTools/bsstructureview.cpp
index 52732a8ccf2d32b003d6af36226b0ff6f984e84d..044d1b0eed73153de2caa204528f74c413bf9a4e 100755
--- a/Code/Seg/BSTools/bsstructureview.cpp
+++ b/Code/Seg/BSTools/bsstructureview.cpp
@@ -87,8 +87,10 @@ bool BSStructureView::processKeyEvent (QKeyEvent *event)
   switch (event->key ())
   {
     case Qt::Key_I : // Info
-      if (event->modifiers () & Qt::ControlModifier) grid->switchScanDisplay ();
-      else grid->toggleDisplay ((event->modifiers () & Qt::ShiftModifier) == 0);
+      if (event->modifiers () & Qt::ControlModifier)
+        grid->switchScanDisplay ();
+      else
+        grid->toggleDisplay ((event->modifiers () & Qt::ShiftModifier) == 0);
       setWindowTitle (grid->itemTitle ());
       scene()->update ();
       update ();
diff --git a/Code/Seg/BSTools/bsstructureview.h b/Code/Seg/BSTools/bsstructureview.h
index 00203be54b1d9773302bd74b739ce05713ff6bb7..51f407a23a6a3fe1ebe716372ff3a7168eaf74d4 100755
--- a/Code/Seg/BSTools/bsstructureview.h
+++ b/Code/Seg/BSTools/bsstructureview.h
@@ -27,11 +27,6 @@ public:
    */
   void setGradientImage (QImage *gim);
 
-  /**
-   * Sets the examined segment from a multi-selection.
-   */
-  inline void setExamined (int index) { grid->setExamined (index); }
-
   /**
    * \brief Redraws the pixel analyzer.
    */
@@ -43,6 +38,7 @@ public:
    */
   bool processKeyEvent (QKeyEvent *event);
 
+
 protected:
 
 private:
diff --git a/Code/Seg/BlurredSegment/bsdetector.cpp b/Code/Seg/BlurredSegment/bsdetector.cpp
index 5bf61d3e02c77e5b6089774df0b35c7e132c3d3e..1bfc85b4ba918463097de3cedc437fb050fe4d4b 100755
--- a/Code/Seg/BlurredSegment/bsdetector.cpp
+++ b/Code/Seg/BlurredSegment/bsdetector.cpp
@@ -30,6 +30,8 @@ BSDetector::BSDetector ()
 {
   gMap = NULL;
 
+  prelimDetectionOn = false;
+  bst0 = (prelimDetectionOn ? new BSTracker () : NULL);
   bst1 = new BSTracker ();
   // bst1->setPixelLackTolerence (bst1->getVicinityThreshold ());
   bst2 = new BSTracker ();
@@ -47,8 +49,10 @@ BSDetector::BSDetector ()
   fittingOn = false;
   densityTestOn = true;
   multiSelection = false;
+  autodet = false;
   autoResol = DEFAULT_AUTO_RESOLUTION;
-  prelimDetectionOn = false;
+  nbmaxtrials = 0;
+  nbtrials = 0;
 
   bspre = NULL;
   bsini = NULL;
@@ -59,15 +63,14 @@ BSDetector::BSDetector ()
 
 BSDetector::~BSDetector ()
 {
+  if (prelimDetectionOn) delete bst0;
   delete bst1;
   delete bst2;
   if (lsf1 != NULL) delete lsf1;
   if (lsf2 != NULL) delete lsf2;
   if (bsini != NULL) delete bsini;
   if (bsf != NULL) delete bsf;
-  vector<BlurredSegment *>::iterator it = mbsini.begin ();
-  while (it != mbsini.end ()) delete (*it++);
-  it = mbsf.begin ();
+  vector <BlurredSegment *>::iterator it = mbsf.begin ();
   while (it != mbsf.end ()) delete (*it++);
 }
 
@@ -75,6 +78,7 @@ BSDetector::~BSDetector ()
 void BSDetector::setGradientMap (VMap *data)
 {
   gMap = data;
+  if (prelimDetectionOn) bst0->setGradientMap (data);
   bst1->setGradientMap (data);
   bst2->setGradientMap (data);
 }
@@ -82,19 +86,22 @@ void BSDetector::setGradientMap (VMap *data)
 
 void BSDetector::detectAll ()
 {
+  autodet = true;
   freeMultiSelection ();
   gMap->setMasking (true);
 
+  bool isnext = true;
+  nbtrials = 0;
   int width = gMap->getWidth ();
   int height = gMap->getHeight ();
-  for (int x = width / 2; x > 0; x -= autoResol)
-    runMultiDetection (Pt2i (x, 0), Pt2i (x, height - 1), Vr2i (0, 1));
-  for (int x = width / 2 + autoResol; x < width - 1; x += autoResol)
-    runMultiDetection (Pt2i (x, 0), Pt2i (x, height - 1), Vr2i (0, 1));
-  for (int y = height / 2; y > 0; y -= autoResol)
-    runMultiDetection (Pt2i (0, y), Pt2i (width - 1, y), Vr2i (1, 0));
-  for (int y = height / 2 + autoResol; y < height - 1; y += autoResol)
-    runMultiDetection (Pt2i (0, y), Pt2i (width - 1, y), Vr2i (1, 0));
+  for (int x = width / 2; isnext && x > 0; x -= autoResol)
+    isnext = runMultiDetection (Pt2i (x, 0), Pt2i (x, height - 1));
+  for (int x = width / 2 + autoResol; isnext && x < width - 1; x += autoResol)
+    isnext = runMultiDetection (Pt2i (x, 0), Pt2i (x, height - 1));
+  for (int y = height / 2; isnext && y > 0; y -= autoResol)
+    isnext = runMultiDetection (Pt2i (0, y), Pt2i (width - 1, y));
+  for (int y = height / 2 + autoResol; isnext && y < height - 1; y += autoResol)
+    isnext = runMultiDetection (Pt2i (0, y), Pt2i (width - 1, y));
 
   gMap->clearMask ();
   gMap->setMasking (false);
@@ -103,11 +110,13 @@ void BSDetector::detectAll ()
 
 void BSDetector::detectSelection (const Pt2i &p1, const Pt2i &p2)
 {
+  autodet = false;
   freeMultiSelection ();
   if (multiSelection)
   {
     gMap->setMasking (true);
-    runMultiDetection (p1, p2, p1.vectorTo (p2));
+    nbtrials = 0;
+    runMultiDetection (p1, p2);
     gMap->clearMask ();
     gMap->setMasking (false);
   }
@@ -115,46 +124,54 @@ void BSDetector::detectSelection (const Pt2i &p1, const Pt2i &p2)
 }
 
 
+void BSDetector::redetect ()
+{
+  if (autodet) detectAll ();
+  else detectSelection (inip1, inip2);
+}
+
+
 void BSDetector::freeMultiSelection ()
 {
-  vector<BlurredSegment *>::iterator it = mbsini.begin ();
-  while (it != mbsini.end ()) delete (*it++);
-  mbsini.clear ();
-  it = mbsf.begin ();
+  vector<BlurredSegment *>::iterator it = mbsf.begin ();
   while (it != mbsf.end ()) delete (*it++);
   mbsf.clear ();
 }
 
 
-void BSDetector::runMultiDetection (const Pt2i &p1, const Pt2i &p2,
-                                    const Vr2i &dir)
+bool BSDetector::runMultiDetection (const Pt2i &p1, const Pt2i &p2)
 {
   vector<Pt2i> pts;
   p1.draw (pts, p2);
   int locmax[pts.size ()];
-  gMap->releaseOrientationConstraint ();
-  int nlm = gMap->localMax (locmax, pts, dir);
-  gMap->restoreOrientationConstraint ();
-  for (int i = 0; i < nlm; i++)
+  int nlm = gMap->localMax (locmax, pts);
+  bool isnext = true;
+  for (int i = 0; isnext && i < nlm; i++)
   {
-    detect (p1, p2, &(pts.at (locmax[i])));
-    if (bsf != NULL)
+    Pt2i ptstart = pts.at (locmax[i]);
+    if (gMap->isFree (ptstart))
     {
-      gMap->setMask (bsf->getAllPoints ());
-      mbsf.push_back (bsf);
-      mbsini.push_back (bsini);
-      bsf = NULL; // to avoid BS deletion
-      bsini = NULL; // to avoid BS deletion
+      detect (p1, p2, true, ptstart);
+      if (bsf != NULL)
+      {
+        gMap->setMask (bsf->getAllPoints ());
+        mbsf.push_back (bsf);
+        bsf = NULL; // to avoid BS deletion
+      }
+      if (++nbtrials == nbmaxtrials) isnext = false;
     }
   }
+  return (isnext);
 }
 
 
-void BSDetector::detect (const Pt2i &p1, const Pt2i &p2, Pt2i *p0)
+void BSDetector::detect (const Pt2i &p1, const Pt2i &p2,
+                         bool centralp, const Pt2i &pc)
 {
   // Clearance
   //----------
   resultValue = RESULT_UNDETERMINED;
+  if (prelimDetectionOn) bst0->clear ();
   bst1->clear ();
   bst2->clear ();
   if (prefilteringOn) lsf1->clear ();
@@ -165,16 +182,19 @@ void BSDetector::detect (const Pt2i &p1, const Pt2i &p2, Pt2i *p0)
   bsini = NULL;
   if (bsf != NULL) delete bsf;
   bsf = NULL;
+  lastTrialOk = false;
 
   if (p1.equals (p2)) return;
-  Pt2i pt1 (p1);
-  Pt2i pt2 (p2);
+  prep1.set (p1);
+  prep2.set (p2);
+  precentralp = centralp;
+  prepc.set (pc);
 
   // Preliminary based on highest gradient without orientation constraint
   //---------------------------------------------------------------------
   if (prelimDetectionOn)
   {
-    bspre = bst1->fastTrack (p1, p2, p0);
+    bspre = bst0->fastTrack (prep1, prep2, precentralp, prepc);
     if (bspre == NULL || bspre->size () < bsMinSize)
     {
       resultValue = (bspre == NULL ? RESULT_PRELIM_NO_DETECTION
@@ -186,22 +206,28 @@ void BSDetector::detect (const Pt2i &p1, const Pt2i &p2, Pt2i *p0)
     int l = v0.chessboard ();
     if (l != 0)
     {
-      Pt2i pc = bspre->getSegment()->centerOfIntersection (p1, p2);
+      Pt2i pcentral = bspre->getSegment()->centerOfIntersection (prep1, prep2);
       AbsRat sw = bspre->segmentRationalWidth ();
       int detw = 2 * (1 + bspre->segmentRationalWidth().floor ());
       if (detw < PRELIM_MIN_HALF_WIDTH) detw = PRELIM_MIN_HALF_WIDTH;
       int dx = (int) ((v0.y () * detw) / l);
       int dy = (int) (- (v0.x () * detw) / l);
-      pt1 = Pt2i (pc.x () + dx, pc.y () + dy);
-      pt2 = Pt2i (pc.x () - dx, pc.y () - dy);
-      p0 = NULL;
+      inip1 = Pt2i (pcentral.x () + dx, pcentral.y () + dy);
+      inip2 = Pt2i (pcentral.x () - dx, pcentral.y () - dy);
+      inicentralp = false;
     }
-    bst1->clear ();
+  }
+  else
+  {
+    inip1.set (p1);
+    inip2.set (p2);
+    inicentralp = centralp;
+    inipc.set (pc);
   }
 
   // Initial detection based on highest gradient without orientation constraint
   //---------------------------------------------------------------------------
-  bsini = bst1->fastTrack (pt1, pt2, p0);
+  bsini = bst1->fastTrack (inip1, inip2, inicentralp, inipc);
   if (bsini == NULL || bsini->size () < bsMinSize)
   {
     resultValue = (bsini == NULL ? RESULT_INITIAL_NO_DETECTION
@@ -213,7 +239,7 @@ void BSDetector::detect (const Pt2i &p1, const Pt2i &p2, Pt2i *p0)
   //-------------
   if (densityTestOn)
   {
-    DigitalStraightLine mydsl (pt1, pt2, DigitalStraightLine::DSL_NAIVE);
+    DigitalStraightLine mydsl (inip1, inip2, DigitalStraightLine::DSL_NAIVE);
     int mydrlf = mydsl.manhattan (bsini->getLastRight ())
                  - mydsl.manhattan (bsini->getLastLeft ());
     if (mydrlf < 0) mydrlf = -mydrlf; // Case of horizontal P1P2
@@ -251,7 +277,7 @@ void BSDetector::detect (const Pt2i &p1, const Pt2i &p2, Pt2i *p0)
   // Scan recentering and fitting
   //-----------------------------
   if (recenteringOn)
-    pCenter = bsini->getSegment()->centerOfIntersection (pt1, pt2);
+    pCenter = bsini->getSegment()->centerOfIntersection (inip1, inip2);
   int bswidth = bst1->fineTracksMaxWidth ();
   if (fittingOn)
   {
@@ -300,13 +326,66 @@ void BSDetector::detect (const Pt2i &p1, const Pt2i &p2, Pt2i *p0)
     }
   }
 
+  lastTrialOk = true;
   resultValue = RESULT_OK;
 }
 
 
+BlurredSegment *BSDetector::getBlurredSegment (int step) const
+{
+  if (step == STEP_PRELIM) return (bspre);
+  else if (step == STEP_INITIAL) return (bsini);
+  else if (mbsf.empty ()) return (bsf);
+  else if (lastTrialOk) return (mbsf.back ());
+  return NULL;
+}
+
+
+void BSDetector::getScanInput (int step, Pt2i &p1, Pt2i &p2,
+                               int &width, Pt2i &pc) const
+{
+  if (step == STEP_PRELIM)
+  {
+    if (prelimDetectionOn)
+    {
+      p1.set (prep1);
+      p2.set (prep2);
+      width = (precentralp ? bst0->fastTrackDefaultWidth () : 0);
+      pc.set (prepc);
+    }
+  }
+  else if (step == STEP_INITIAL)
+  {
+    p1.set (inip1);
+    p2.set (inip2);
+    width = (inicentralp ? bst1->fastTrackDefaultWidth () : 0);
+    pc.set (inipc);
+  }
+}
+
+
+const vector <vector <Pt2i> > BSDetector::getFinalScans () const
+{
+  return (bst2->getScans ());
+}
+
+
+bool BSDetector::finalScansRecordOn () const
+{
+  return (bst2->scanRecordOn ());
+}
+
+
+void BSDetector::setFinalScansRecord (bool status)
+{
+  bst2->setScanRecord (status);
+  if (status) redetect ();
+}
+
 
 void BSDetector::switchOrthoScans ()
 {
+  if (prelimDetectionOn) bst0->switchOrthoScans ();
   bst1->switchOrthoScans ();
   bst2->switchOrthoScans ();
 }
@@ -331,7 +410,7 @@ void BSDetector::switchFiltering (int step)
     filteringOn = ! filteringOn;
     if (filteringOn && lsf2 == NULL) lsf2 = new LineSpaceFilter ();
   }
-  else
+  else if (step == STEP_INITIAL)
   {
     prefilteringOn = ! prefilteringOn;
     if (prefilteringOn && lsf1 == NULL) lsf1 = new LineSpaceFilter ();
@@ -345,3 +424,20 @@ bool BSDetector::incConnectedComponentMinSize (bool increase)
   ccMinSize += (increase ? 1 : -1);
   return true;
 }
+
+
+void BSDetector::switchPreliminary ()
+{
+  if (prelimDetectionOn)
+  {
+    delete bst0;
+    prelimDetectionOn = false;
+  }
+  else
+  {
+    prelimDetectionOn = true;
+    bst0 = new BSTracker ();
+    bst0->setGradientMap (gMap);
+    if (bst1->orthoScansOn ()) bst0->switchOrthoScans ();
+  }
+}
diff --git a/Code/Seg/BlurredSegment/bsdetector.h b/Code/Seg/BlurredSegment/bsdetector.h
index 746b4c98c5343785cd279b31b77f39f40387ec14..95a38bbde3f217c0333f7400c8be3b3465445cd0 100755
--- a/Code/Seg/BlurredSegment/bsdetector.h
+++ b/Code/Seg/BlurredSegment/bsdetector.h
@@ -82,6 +82,11 @@ public:
    */
   void detectSelection (const Pt2i &p1, const Pt2i &p2);
 
+  /**
+   * \brief Runs the last detection again.
+   */
+  void redetect ();
+
   /**
    * \brief Detects a blurred segment between two input points.
    * Step 1: For each scan line, one candidate is selected
@@ -94,28 +99,23 @@ public:
    * Note : Multi-detection along a stroke requires an initial start point.
    * @param p1 First input point.
    * @param p2 Second input point.
-   * @param p0 Initial segment start point (if different from NULL).
+   * @param centralp Set to true if the central point is provided.
+   * @param pc Initial central point.
    */
-  void detect (const Pt2i &p1, const Pt2i &p2, Pt2i *p0 = NULL);
+  void detect (const Pt2i &p1, const Pt2i &p2,
+               bool centralp = false, const Pt2i &pc = Pt2i ());
 
   /**
-   * \brief Returns the last detected blurred segment at given step.
+   * \brief Returns the detected blurred segment at given step.
    * @param step Detection step.
    */
-  inline BlurredSegment *getBlurredSegment (int step = STEP_FINAL) {
-    if (step == STEP_FINAL) return (bsf);
-    else if (step == STEP_INITIAL) return (bsini);
-    else if (step == STEP_PRELIM) return (bspre);
-    return (bsf);
-  }
+  BlurredSegment *getBlurredSegment (int step = STEP_FINAL) const;
     
   /**
-   * \brief Returns the list of detected blurred segments at given step.
-   * @param step Detection step. Preliminary step not considered here.
+   * \brief Returns the list of detected blurred segments at final step.
    */
-  inline vector<BlurredSegment *> getBlurredSegments (int step = STEP_FINAL) {
-    return (step == STEP_FINAL ? mbsf : mbsini);
-  }
+  inline const vector<BlurredSegment *> getBlurredSegments () const {
+    return (mbsf); }
 
   /**
    * \brief Avoids the deletion of the last extracted blurred segment.
@@ -216,7 +216,7 @@ public:
   /**
    * \brief Switches preliminary detection modality.
    */
-  inline void switchPreliminary () { prelimDetectionOn = ! prelimDetectionOn; }
+  void switchPreliminary ();
 
   /**
    * \brief Returns the edge direction constraint status.
@@ -277,44 +277,20 @@ public:
   inline void switchMultiSelection () { multiSelection = ! multiSelection; }
 
   /**
-   * \brief Returns the upper bound of the final scan of the given step.
-   * @param step Initial step addressed if set to 0, final step otherwise.
+   * \brief Returns the scan lines at final step.
    */
-  inline vector<Pt2i> getScanBound1 (int step) const {
-    return (step == STEP_FINAL ?
-            bst2->getScanBound1 () : bst1->getScanBound1 ()); }
+  const vector <vector <Pt2i> > getFinalScans () const;
 
   /**
-   * \brief Returns the lower bound of the final scan of the given step.
-   * @param step Initial step addressed if set to 0, final step otherwise.
-   */
-  inline vector<Pt2i> getScanBound2 (int step) const {
-    return (step == STEP_FINAL ?
-            bst2->getScanBound2 () : bst1->getScanBound2 ()); }
-
-  /**
-   * \brief Returns the scan lines of the given step.
-   * @param step Initial step addressed if set to 0, final step otherwise.
-   */
-  inline vector <vector <Pt2i> > getScans (int step) const {
-    return (step == STEP_FINAL ? bst2->getScans () : bst1->getScans ()); }
-
-  /**
-   * \brief Returns whether the scan record modality is set for the given step.
-   * @param step Initial step addressed if set to 0, final step otherwise.
+   * \brief Returns whether the final scan record modality is set.
    */
-  inline bool scanRecordOn (int step) {
-    return (step == STEP_FINAL ?
-      bst2->scanRecordOn () : bst1->scanRecordOn ()); }
+  bool finalScansRecordOn () const;
 
   /**
-   * \brief Sets the scan record modality of initial or final step.
-   * @param step Initial step addressed if set to 0, final step otherwise.
+   * \brief Sets the scan record modality at final step.
    * @param status Sets on if true, off otherwise.
    */
-  inline void setScanRecord (int step, bool status) {
-    if (step == STEP_FINAL) bst2->setScanRecord (status);
-    else bst1->setScanRecord (status); }
+  void setFinalScansRecord (bool status);
 
   /**
    * \brief Toggles the initial step bounding.
@@ -415,7 +391,9 @@ public:
    * @param step Initial step addressed if set to 0, final step otherwise.
    */
   inline bool isFiltering (int step) const {
-    return (step == STEP_FINAL ? filteringOn : prefilteringOn); }
+    if (step == STEP_FINAL) return (filteringOn);
+    else if (step == STEP_INITIAL) return (prefilteringOn);
+    else return false; }
 
   /**
    * \brief Toggles the use of the given line space based filter.
@@ -466,6 +444,37 @@ public:
    */
   bool incConnectedComponentMinSize (bool increase);
 
+  /*
+   * \brief Returns the count of trials in a multi-detection.
+   */
+  inline int countOfTrials () const { return (nbtrials); }
+
+  /**
+   * \brief Sets the maximum number of trials in a multi-detection.
+   * @param nb Number of trials (0 if illimited).
+   */
+  inline void setMaxTrials (int nb) { nbmaxtrials = nb; }
+
+  /**
+   * \brief Returns the maximum number of trials for a multi-detection.
+   */
+  inline int getMaxTrials () const { return nbmaxtrials; }
+
+  /**
+   * \brief Retuns whether the last trial was successful.
+   */
+  inline bool isLastTrialOk () { return lastTrialOk; }
+
+  /**
+   * \brief Gets the last detection inputs.
+   * @param step Detection step.
+   * @param p1 Input stroke first point to fill in.
+   * @param p2 Input stroke end point to fill in.
+   * @param width Input stroke width to fill in.
+   * @param pc Input central point to fill in.
+   */
+  void getScanInput (int step, Pt2i &p1, Pt2i &p2, int &width, Pt2i &pc) const;
+
 
 private :
 
@@ -504,22 +513,46 @@ private :
   bool densityTestOn;
   /** Segment multi-selection modality status. */
   bool multiSelection;
+  /** Flag indicating if the last trial was successful. */
+  bool lastTrialOk;
+  /** Count of trials in a multi-detection. */
+  int nbtrials;
+  /** Maximum number of trials in a multi-detection. */
+  int nbmaxtrials;
+  /** Automatic detection modality. */
+  bool autodet;
   /** Grid resolution for the automatic extraction. */
   int autoResol;
   /** Result of the blurred segment extraction */
   int resultValue;
 
+  /** Last input start point. */
+  Pt2i prep1;
+  /** Last input end point. */
+  Pt2i prep2;
+  /** Last input central point. */
+  Pt2i prepc;
+  /** Last input central point modality. */
+  bool precentralp;
   /** Preliminary stage modality. */
   bool prelimDetectionOn;
+  /** Preliminary rough tracker. */
+  BSTracker *bst0;
   /** Preliminary detected blurred segment. */
   BlurredSegment *bspre;
 
   /** Initial rough tracker. */
   BSTracker *bst1;
+  /** Last input start point for initial step. */
+  Pt2i inip1;
+  /** Last input end point for initial step. */
+  Pt2i inip2;
+  /** Last input central point for initial step. */
+  Pt2i inipc;
+  /** Last input central point modality for initial step. */
+  bool inicentralp;
   /** Initially detected blurred segment (initial step result). */
   BlurredSegment *bsini;
-  /** Detected blurred segments in case of multi-detection (initial step). */
-  vector<BlurredSegment *> mbsini;
 
   /** Fine tracker. */
   BSTracker *bst2;
@@ -541,12 +574,11 @@ private :
 
   /**
    * \brief Detects all blurred segments between two input points.
+   *   Returns the continuation modality.
    * @param p1 First input point.
    * @param p2 Second input point.
-   * @param dir Direction of the selection (factored P1P2).
    */
-  void runMultiDetection (const Pt2i &p1, const Pt2i &p2,
-                          const Vr2i &dir);
+  bool runMultiDetection (const Pt2i &p1, const Pt2i &p2);
 
   /**
    * \brief Resets the multi-selection list.
diff --git a/Code/Seg/BlurredSegment/bstracker.cpp b/Code/Seg/BlurredSegment/bstracker.cpp
index 50deb34c40d4359bafcb61459a0289e00d23eadc..a5931ae0f6d446750121cb1c8380cbf45a22e23c 100755
--- a/Code/Seg/BlurredSegment/bstracker.cpp
+++ b/Code/Seg/BlurredSegment/bstracker.cpp
@@ -77,12 +77,12 @@ void BSTracker::setGradientMap (VMap *data)
 
 
 BlurredSegment *BSTracker::fastTrack (const Pt2i &p1, const Pt2i &p2,
-                                      Pt2i *p0)
+                                      bool centralp, const Pt2i &pc)
 {
   // Creates the scanner
   DirectionalScanner *ds = NULL;
-  if (p0 != NULL)
-    ds = scanp.getScanner (*p0, p1.vectorTo (p2), 4 * imaxWidth, false);
+  if (centralp)
+    ds = scanp.getScanner (pc, p1.vectorTo (p2), 4 * imaxWidth, false);
   else ds = scanp.getScanner (p1, p2);
   if (ds == NULL) return NULL;
 
@@ -102,7 +102,7 @@ BlurredSegment *BSTracker::fastTrack (const Pt2i &p1, const Pt2i &p2,
   }
   int candide;
   Pt2i pfirst;
-  if (p0 != NULL) pfirst.set (p0->x (), p0->y ());
+  if (centralp) pfirst.set (pc.x (), pc.y ());
   else
   {
     candide = gMap->largestIn (pix);
diff --git a/Code/Seg/BlurredSegment/bstracker.h b/Code/Seg/BlurredSegment/bstracker.h
index 4812cdeb9e36845c0436645b42ed19fa72ec2f15..58ce273ff40561539f64c7ff8a931f84ebdf498c 100755
--- a/Code/Seg/BlurredSegment/bstracker.h
+++ b/Code/Seg/BlurredSegment/bstracker.h
@@ -38,10 +38,11 @@ public:
    * \brief Builds and returns a blurred segment from only gradient maximum.
    * @param p1 Initial stroke start point.
    * @param p2 Initial stroke end point.
-   * @param p0 Initial segment start point (if different from NULL).
+   * @param centralp Set to true if a start point is provided.
+   * @param pc Initial segment start point (if centralp is true).
    */
   BlurredSegment *fastTrack (const Pt2i &p1, const Pt2i &p2,
-                             Pt2i *p0 = NULL);
+                             bool centralp = false, const Pt2i &pc = Pt2i ());
 
   /**
    * \brief Builds and returns a blurred segment from local gradient maxima.
@@ -146,19 +147,16 @@ public:
   inline bool dynamicScansOn () { return dynamicScans; }
 
   /**
-   * \brief Returns the upper bound of the final scan.
+   * \brief Returns the registered upper bounds of the final scan lines.
+   * @param side Upper bound if set to 1, lower bound otherwise.
    */
-  inline vector<Pt2i> getScanBound1 () const { return scanBound1; }
+  inline vector<Pt2i> getScanBound (int side) const {
+    return (side == 1 ? scanBound1 : scanBound2); }
 
   /**
-   * \brief Returns the lower bound of the final scan.
+   * \brief Returns the registered scan lines.
    */
-  inline vector<Pt2i> getScanBound2 () const { return scanBound2; }
-
-  /**
-   * \brief Returns the scan lines.
-   */
-  inline vector <vector <Pt2i> > getScans () const { return scanLine; }
+  inline const vector <vector <Pt2i> > &getScans () const { return scanLine; }
 
   /**
    * \brief Returns whether the scan record modality is set.
@@ -211,6 +209,12 @@ public:
    */
   inline bool orthoScansOn () { return orthoScan; }
 
+  /**
+   * \brief Returns the fast track default max width.
+   * This value is used when a central point is given.
+   */
+  inline int fastTrackDefaultWidth () const { return (4 * imaxWidth); }
+
 
 private :
 
diff --git a/Code/Seg/DirectionalScanner/directionalscannero1.cpp b/Code/Seg/DirectionalScanner/directionalscannero1.cpp
index d3a216dc3db0a8b2f954cbe6e3c2633295378025..5f61fde00d29284f80eb9fbe4c296296bf6e1dcd 100755
--- a/Code/Seg/DirectionalScanner/directionalscannero1.cpp
+++ b/Code/Seg/DirectionalScanner/directionalscannero1.cpp
@@ -54,6 +54,10 @@ DirectionalScannerO1::DirectionalScannerO1 (
 
   rcx = lcx;
   rcy = lcy;
+/** ZZZ */
+ccx = lcx;
+ccy = lcy;
+/** ZZZ */
   lst1 = steps;
   rst1 = steps;
   lst2 = steps;
@@ -98,6 +102,10 @@ DirectionalScannerO1::DirectionalScannerO1 (
 
   rcx = lcx;
   rcy = lcy;
+/** ZZZ */
+ccx = lcx;
+ccy = lcy;
+/** ZZZ */
   lst1 = steps;
   rst1 = steps;
   lst2 = steps;
diff --git a/Code/Seg/DirectionalScanner/directionalscannero2.cpp b/Code/Seg/DirectionalScanner/directionalscannero2.cpp
index 424f435ea6fbd748885a2361800684a4321c8669..dbf43d8fc9aeffeae44c7bdb7943dd47d08915a9 100755
--- a/Code/Seg/DirectionalScanner/directionalscannero2.cpp
+++ b/Code/Seg/DirectionalScanner/directionalscannero2.cpp
@@ -54,6 +54,10 @@ DirectionalScannerO2::DirectionalScannerO2 (
 
   rcx = lcx;
   rcy = lcy;
+/** ZZZ */
+ccx = lcx;
+ccy = lcy;
+/** ZZZ */
   lst1 = steps;
   rst1 = steps;
   lst2 = steps;
@@ -98,6 +102,10 @@ DirectionalScannerO2::DirectionalScannerO2 (
 
   rcx = lcx;
   rcy = lcy;
+/** ZZZ */
+ccx = lcx;
+ccy = lcy;
+/** ZZZ */
   lst1 = steps;
   rst1 = steps;
   lst2 = steps;
diff --git a/Code/Seg/DirectionalScanner/directionalscannero7.cpp b/Code/Seg/DirectionalScanner/directionalscannero7.cpp
index 9d4296f4d84e332c9ec541ac2f609dbbf4f71873..bf6ead583a61e4b281fe6983eba3d8ef921d8dc4 100755
--- a/Code/Seg/DirectionalScanner/directionalscannero7.cpp
+++ b/Code/Seg/DirectionalScanner/directionalscannero7.cpp
@@ -54,6 +54,10 @@ DirectionalScannerO7::DirectionalScannerO7 (
 
   rcx = lcx;
   rcy = lcy;
+/** ZZZ */
+ccx = lcx;
+ccy = lcy;
+/** ZZZ */
   lst1 = steps;
   rst1 = steps;
   lst2 = steps;
@@ -98,6 +102,10 @@ DirectionalScannerO7::DirectionalScannerO7 (
 
   rcx = lcx;
   rcy = lcy;
+/** ZZZ */
+ccx = lcx;
+ccy = lcy;
+/** ZZZ */
   lst1 = steps;
   rst1 = steps;
   lst2 = steps;
diff --git a/Code/Seg/DirectionalScanner/directionalscannero8.cpp b/Code/Seg/DirectionalScanner/directionalscannero8.cpp
index eaadecd256013349d0c779e0e631c7dfa192d9f6..83cdc92a6079db841eaa00bba153433f70fbb56c 100755
--- a/Code/Seg/DirectionalScanner/directionalscannero8.cpp
+++ b/Code/Seg/DirectionalScanner/directionalscannero8.cpp
@@ -54,6 +54,10 @@ DirectionalScannerO8::DirectionalScannerO8 (
 
   rcx = lcx;
   rcy = lcy;
+/** ZZZ */
+ccx = lcx;
+ccy = lcy;
+/** ZZZ */
   lst1 = steps;
   rst1 = steps;
   lst2 = steps;
@@ -98,6 +102,10 @@ DirectionalScannerO8::DirectionalScannerO8 (
 
   rcx = lcx;
   rcy = lcy;
+/** ZZZ */
+ccx = lcx;
+ccy = lcy;
+/** ZZZ */
   lst1 = steps;
   rst1 = steps;
   lst2 = steps;
diff --git a/Code/Seg/ImageTools/vmap.cpp b/Code/Seg/ImageTools/vmap.cpp
index 0796fb43b383379ec644dde55dd98a3b63d736ff..5df08bdd353faeb058331a8ba93769fabff57699 100755
--- a/Code/Seg/ImageTools/vmap.cpp
+++ b/Code/Seg/ImageTools/vmap.cpp
@@ -15,7 +15,6 @@ const int VMap::TYPE_FULL_BLACK_HAT = 6;
 const int VMap::TYPE_FULL_MORPHO = 7;
 
 const int VMap::NEAR_SQ_ANGLE = 80;  // 80% (roughly 25 degrees)
-const int VMap::LARGE_SQ_ANGLE = 25;  // 25% (60 degrees)
 const int VMap::DEFAULT_GRADIENT_THRESHOLD = 30;
 
 
@@ -119,7 +118,6 @@ VMap::VMap (int width, int height, int *data, int type)
   masking = false;
   angleThreshold = NEAR_SQ_ANGLE;
   orientedGradient = false;
-  formerOrientedGradient = false;
 }
 
 
@@ -223,7 +221,6 @@ VMap::VMap (int width, int height, int **data, int type)
   masking = false;
   angleThreshold = NEAR_SQ_ANGLE;
   orientedGradient = false;
-  formerOrientedGradient = false;
 }
 
 
@@ -520,7 +517,7 @@ int VMap::keepDirectedElementsIn (const vector<Pt2i> &pix,
 }
 
 
-int VMap::localMax (int *lmax, const vector<Pt2i> &pix, const Vr2i &gref) const
+int VMap::localMax (int *lmax, const vector<Pt2i> &pix) const
 {
   // Builds the gradient norm signal
   int n = (int) pix.size ();
@@ -533,8 +530,27 @@ int VMap::localMax (int *lmax, const vector<Pt2i> &pix, const Vr2i &gref) const
   int count = searchLocalMax (lmax, n, gn);
 
   // Prunes the already selected candidates
-  if (masking)
-    count = keepFreeElementsIn (pix, count, lmax);
+  count = keepFreeElementsIn (pix, count, lmax);
+
+  // Sorts candidates by gradient magnitude
+  sortMax (lmax, count, gn);
+
+  delete gn;
+  return count;
+}
+
+
+int VMap::localMax (int *lmax, const vector<Pt2i> &pix, const Vr2i &gref) const
+{
+  // Builds the gradient norm signal
+  int n = (int) pix.size ();
+  int *gn = new int[n];
+  int i = 0;
+  vector<Pt2i>::const_iterator it = pix.begin ();
+  while (it != pix.end ()) gn[i++] = magn (*it++);
+
+  // Gets the local maxima
+  int count = searchLocalMax (lmax, n, gn);
 
   // Prunes the candidates with opposite gradient
   if (orientedGradient)
diff --git a/Code/Seg/ImageTools/vmap.h b/Code/Seg/ImageTools/vmap.h
index 7ed1903e59b58ba48cd19167b2be0f659d9fa3e2..0d55928ddca75d52f0280497d01aa9a8082e50a9 100755
--- a/Code/Seg/ImageTools/vmap.h
+++ b/Code/Seg/ImageTools/vmap.h
@@ -180,6 +180,15 @@ public:
 
   /**
    * \brief Gets filtered and sorted local gradient maxima.
+   * Local max already used are pruned.
+   * Returns the count of found gradient maxima.
+   * @param lmax Local max index array.
+   * @param pix Provided points.
+   */
+  int localMax (int *lmax, const vector<Pt2i> &pix) const;
+
+  /**
+   * \brief Gets filtered and sorted local oriented gradient maxima.
    * Local maxima are filtered according to the gradient direction and sorted.
    * Returns the count of found gradient maxima.
    * @param lmax Local max index array.
@@ -210,23 +219,6 @@ public:
   inline void switchOrientationConstraint () {
     orientedGradient = ! orientedGradient; }
 
-  /**
-   * \brief Temporarily releases the direction constraint for large angle tests.
-   */
-  inline void releaseOrientationConstraint () {
-    formerOrientedGradient = orientedGradient;
-    orientedGradient = false;
-    angleThreshold = LARGE_SQ_ANGLE;
-  }
-
-  /**
-   * \brief Restores the direction constraint status for fine angle tests.
-   */
-  inline void restoreOrientationConstraint () {
-    orientedGradient = formerOrientedGradient;
-    angleThreshold = NEAR_SQ_ANGLE;
-  }
-
   /**
    * \brief Clears the occupancy mask.
    */
@@ -244,13 +236,18 @@ public:
    */
   inline void setMasking (bool status) { masking = status; }
 
+  /**
+   * \brief Sets mask activation on or off
+   * @param status Required activation status.
+   */
+  inline bool isFree (const Pt2i &pt) const {
+    return (! mask[pt.y () * width + pt.x ()]); }
+
 
 private:
 
   /** Default value for near angular deviation tests. */
   static const int NEAR_SQ_ANGLE;
-  /** Default value for large angular deviation tests. */
-  static const int LARGE_SQ_ANGLE;
   /** Effective value for the angular deviation test. */
   int angleThreshold;
   /** Default threshold value for the gradient selection. */
@@ -277,8 +274,6 @@ private:
   int gmagThreshold;
   /** Direction constraint for local gradient maxima. */
   bool orientedGradient;
-  /** Registred direction constraint for local gradient maxima. */
-  bool formerOrientedGradient;
 
 
   /**