     }
     return (rectFonts, collision, endCollision)
   }
+  
+  override func layoutSubviews() {
+    super.layoutSubviews()
+    setNeedsDisplay()
+    slider.setNeedsDisplay()
+  }
 }
 
-fileprivate func getFont(bold: Bool) -> UIFont? {
+class MySlider : UISlider {
+  let ballRadius : CGFloat = 6.0
+  let horzFudge : CGFloat = 4.0
+  
+  var maxBallColor : UIColor = UIColor.lightGray
+  let minBallColor : UIColor = UIColor.darkGray
+  
+  var values : [String] = [] {
+    didSet {
+      self.invalidateIntrinsicContentSize()
+    }
+  }
+  var discreteValue : Int = 0
+  var ballRects : [CGRect] = []
+  var maxTextWidthAllowed : CGFloat = 0.0
+  
+  override func layoutSubviews() {
+    super.layoutSubviews()
+    ballRects.removeAll()
+    let width : CGFloat = bounds.width
+    let extra = ceil(bounds.height / 2.0)
+    let y = bounds.origin.y + extra
+    let cx = width / CGFloat(values.count - 1)
+    maxTextWidthAllowed = cx
+    
+    let halfway = values.count / 2
+    let even = values.count % 2 == 0
+    
+    // Do the fudgy thing.   In a perfect world, I'd figure out what exact
+    // curve Apple is using to fudge the visual values of the 'ball' on the
+    // slider, and match that here.   This linear fudging seems close enough to
+    // get the labels and little balls and the big balls to pretty much look
+    // like they match up on the line. I judge that, if more precision is
+    // is needed, it'd be easier to just ditch the UISlider altogether, and
+    // just draw it all myself.   It's just a BezierPath with some shading,
+    // and a straight line.
+    for i in 0..<self.values.count {
+      var px : CGFloat = CGFloat(i) * cx + self.ballRadius
+      if i < halfway && i > 0 {
+        px += horzFudge
+      } else if i >= halfway && i < values.count - 1{
+        if i != halfway || even {
+          px -= horzFudge
+        }
+      }
+      
+      let center : CGPoint = CGPoint(x: px, y: y)
+      var rect = CGRect(x: center.x - self.ballRadius,
+                        y: center.y - self.ballRadius, width: self.ballRadius * 2.0,
+                        height: self.ballRadius * 2.0)
+      
+      if i == self.discreteValue {
+        ballRects.append(rect)
+        continue
+      }
+      
+      if i == self.values.count - 1 {
+        let rectOriginX = rect.origin.x
+        let newRectOriginX = self.bounds.width - (self.ballRadius * 2)
+        let offsetX = newRectOriginX - rectOriginX
+        rect = rect.offsetBy(dx: offsetX, dy: 0.0)
+      }
+      
+      ballRects.append(rect)
+    }
+  }
+  
+  override func draw(_ rect: CGRect) {
+    maximumTrackTintColor = maxBallColor
+    minimumTrackTintColor = minBallColor
+    
+    super.draw(rect)
+    
+    guard let context = UIGraphicsGetCurrentContext() else {
+      return
+    }
+    
+    for i in 0..<ballRects.count {
+      if i == discreteValue {
+        continue
+      }
+      let ballRect = ballRects[i]
+      context.saveGState()
+      let ball = UIBezierPath(ovalIn: ballRect)
+      if i < discreteValue {
+        minBallColor.setFill()
+        ball.fill()
+      } else {
+        maxBallColor.setFill()
+        ball.fill()
+      }
+      context.restoreGState()
+    }
+    
+  }
+}
+
+// This is just a placeholder for whatever you need to do, Aarti.
+fileprivate func getAdaptiveFont(bold: Bool) -> UIFont? {
   if false == bold {
     return UIFont.systemFont(ofSize: 12.0)
   }

    return CGSize(width: width, height: height)
  }
  
  override public func layoutSubviews() {
    super.layoutSubviews()
    layoutTrackLine()
    calculateLittleBallRects()
    recalculateThumbX()
    setNeedsDisplay()
  }
  
  fileprivate func recalculateThumbX() {
    guard trackRect.width > 0, values.count > 1 else {
      return
    }
  
    thumbX = trackRect.width / CGFloat(values.count - 1) * CGFloat(discreteValue)
  }
  
  fileprivate func layoutTrackLine() {
    let trackSize : CGSize = CGSize(width: frame.width, height: trackHeight)
    
    trackRect = CGRect(x: 0, y: (frame.height - trackSize.height) / 2,
      width: trackSize.width, height: trackSize.height)
    
    setNeedsDisplay()
  }
  
  fileprivate func calculateLittleBallRects() {
    ballRects.removeAll()
    let width : CGFloat = bounds.width
    let extra = ceil(bounds.height / 2.0)
    let y = bounds.origin.y + extra
    let cx = width / CGFloat(values.count - 1)
    maxTextWidthAllowed = cx
    
    for i in 0..<self.values.count {
      let px : CGFloat = CGFloat(i) * cx + self.ballRadius
      let center : CGPoint = CGPoint(x: px, y: y)
      var rect = CGRect(x: center.x - self.ballRadius,
        y: center.y - self.ballRadius, width: self.ballRadius * 2.0,
        height: self.ballRadius * 2.0)
      
      if i == self.values.count - 1 {
        let rectOriginX = rect.origin.x
        let newRectOriginX = self.bounds.width - (self.ballRadius * 2)
        let offsetX = newRectOriginX - rectOriginX
        rect = rect.offsetBy(dx: offsetX, dy: 0.0)
      }
      
      ballRects.append(rect)
    }
  }
  
  override public func touchesBegan(_ touches: Set<UITouch>,
    with event: UIEvent?) {
    
    guard let location = locationOfFirstTouch(inTouches: touches) else {
      return
    }
    let thumbcenter = thumbX + ballRadius
    touchOffsetX = location.x - thumbcenter
  }
  
  override public func touchesMoved(_ touches: Set<UITouch>,
    with event: UIEvent?) {
    
    guard let location = locationOfFirstTouch(inTouches: touches) else {
      return
    }
    
    let desiredX = desiredThumbX(touchX: location.x)
    moveThumbTo(x: desiredX, animationDuration: 0.0)
  }
  
  override public func touchesEnded(_ touches: Set<UITouch>,
    with event: UIEvent?) {
    
    guard let location = locationOfFirstTouch(inTouches: touches) else {
      return
    }
    
    let desiredX = desiredThumbX(touchX: location.x)
    moveThumbTo(x: desiredX, animationDuration: 0.0, discrete: true)
    touchOffsetX = 0.0
  }
  
  fileprivate func desiredThumbX(touchX : CGFloat) -> CGFloat {
    return touchX - touchOffsetX
  }
  
  fileprivate func locationOfFirstTouch(inTouches touches : Set<UITouch>)
    -> CGPoint? {
      
    guard let touch = touches.first else {
      return nil
    }
    return touch.location(in: touch.view)
  }
  
  fileprivate func showDiscretion(value : CGFloat) -> Int {
    guard values.count > 1, value >= 0.0, trackRect.width > 0 else {
      return 0
    }
    
    let scaledToValueSetValue = value / trackRect.width *
      CGFloat(values.count - 1)
    
    var intValue = Int(scaledToValueSetValue)
    if scaledToValueSetValue - CGFloat(intValue) > 0.5 {
      intValue += 1
    }
    return intValue
  }

  
  override public func draw(_ rect: CGRect) {
    super.draw(rect)
    
    drawTrackLine()
    guard let context = UIGraphicsGetCurrentContext() else {
      return
    }
    
    let currentThumbCenter = thumbX + selectorRadius
    
    for i in 0..<ballRects.count {
      let ballRect = ballRects[i]
      context.saveGState()
      let ball = UIBezierPath(ovalIn: ballRect)
      // The zeroth ball is always painted the max color
      if ballRect.origin.x < currentThumbCenter  || i == 0 {
        maximumTrackTintColor.setFill()
        ball.fill()
      } else {
        minimumTrackTintColor.setFill()
        ball.fill()
      }
      context.restoreGState()
    }
    
    drawThumb()
    drawLabels()
  }
  
  fileprivate func drawLabels() {
    let tuple = getTextRectFontsAndCollisionInfo()
    let textRectFonts = tuple.0
    let collision = tuple.1

    var font : UIFont
  }
  
 
  fileprivate func getTextRectFontsAndCollisionInfo() -> ([TextRectFont], Bool, Bool) {
    var collision : Bool = false
    var endCollision : Bool = false
    var rectFonts : [TextRectFont] = []
    
    let ballRects = slider.ballRects
    let count = ballRects.count
    
    let sliderBottom = slider.frame.origin.y + slider.frame.height
    
    for i in 0..<count {
      let ballRect = ballRects[i]
      let text = values[i]
      let nsText = NSString(string: text)
      
      let bold = i == value
      guard let font = getAdaptiveFont(bold: bold) else {
        continue
      }
      
      let textSize = nsText.size(attributes: [NSFontAttributeName : font])
      
      var x : CGFloat = ballRect.center.x - textSize.width / 2
      if i == 0 {
        x = 0
      } else if i == ballRects.count - 1 {
