docs: private int treeHull_(Point2D pt_pivot) {
  		assert (m_tree_hull.size(-1) >= 2);
  
  		int p = -1;
  
  		do {
  			int first = m_tree_hull.getFirst(-1);
  			int last = m_tree_hull.getLast(-1);
  			int t0 = m_tree_hull.getElement(first);
  			int tm = m_tree_hull.getElement(last);
  
  			Point2D pt_0 = new Point2D(); // should the memory be cached?
  			Point2D pt_m = new Point2D(); // should the memory be cached?
  			m_call_back.getXY(t0, pt_0);
  			m_call_back.getXY(tm, pt_m);
  
  			assert (!pt_0.isEqual(pt_m, NumberUtils.doubleEps())); // assert that the gap is not closed
  
  			int orient_m_p_0 = Point2D.orientationRobust(pt_m, pt_pivot, pt_0); // determines case 1, 2, 3
  
  			if (isClockwise_(orient_m_p_0)) {// Case 1: tp->t0->tm is clockwise
  
  				p = m_tree_hull.addBiggestElement(-1, -1); // set place holder to -1 for case 1.
  				int l = treeHullWalkBackward_(pt_pivot, last, first);
  
  				if (l != first)
  					treeHullWalkForward_(pt_pivot, first, m_tree_hull.getPrev(l));
  
  				continue;
  			}
  
  			if (isCounterClockwise_(orient_m_p_0)) {// Case 2: tp->tm->t0 is clockwise
  				int k = m_tree_hull.getRoot(-1), k_min = m_tree_hull.getFirst(-1), k_max = m_tree_hull.getLast(-1), k_prev;
  				int tk, tk_prev;
  				Point2D pt_k = new Point2D();
  				Point2D pt_k_prev = new Point2D();
  
  				while (k_min != m_tree_hull.getPrev(k_max)) {// binary search to find k such that t0->tp->tj holds (i.e. clockwise) for j >= k. Hence, tj->tp->t0 is clockwise (or degenerate) for j < k.
  					tk = m_tree_hull.getElement(k);
  					m_call_back.getXY(tk, pt_k);
  					int orient_k_p_0 = Point2D.orientationRobust(pt_k, pt_pivot, pt_0);
  
  					if (isCounterClockwise_(orient_k_p_0)) {
  						k_max = k;
  						k = m_tree_hull.getLeft(k);
  					} else {
  						k_min = k;
  						k = m_tree_hull.getRight(k);
  					}
  				}
  
  				k = k_max;
  				k_prev = k_min;
  				tk = m_tree_hull.getElement(k);
  				tk_prev = m_tree_hull.getElement(k_prev);
  				m_call_back.getXY(tk, pt_k);
  				m_call_back.getXY(tk_prev, pt_k_prev);
  				assert (isCounterClockwise_(Point2D.orientationRobust(pt_k, pt_pivot, pt_0)) && !isCounterClockwise_(Point2D.orientationRobust(pt_k_prev, pt_pivot, pt_0)));
  				assert (k_prev != first || isCounterClockwise_(Point2D.orientationRobust(pt_k, pt_pivot, pt_0)));
  
  				if (k_prev != first) {
  					int orient_k_prev_p_k = Point2D.orientationRobust(pt_k_prev, pt_pivot, pt_k);
  
  					if (!isClockwise_(orient_k_prev_p_k))
  						continue; // pt_pivot is inside the hull (or on the boundary)
  				}
  
  				p = m_tree_hull.addElementAtPosition(k_prev, k, -2, true, false, -1); // set place holder to -2 for case 2.
  				treeHullWalkForward_(pt_pivot, k, last);
  				treeHullWalkBackward_(pt_pivot, k_prev, first);
  
  				continue;
  			}
  
  			assert (isDegenerate_(orient_m_p_0));
  			{// Case 3: degenerate
  				int between = isBetween_(pt_pivot, pt_m, pt_0);
  
  				if (between == -1) {
  					int l = m_tree_hull.getPrev(last);
  					m_tree_hull.deleteNode(last, -1);
  					p = m_tree_hull.addBiggestElement(-3, -1); // set place holder to -3 for case 3.
  					treeHullWalkBackward_(pt_pivot, l, first);
  				} else if (between == 1) {
  					int j = m_tree_hull.getNext(first);
  					m_tree_hull.deleteNode(first, -1);
  					p = m_tree_hull.addElementAtPosition(-1, j, -3, true, false, -1); // set place holder to -3 for case 3.
  					treeHullWalkForward_(pt_pivot, j, last);
  				}
  
  				continue;
  			}
  
  		} while (false);
  
  		return p;
  	}