         case EaseInOut
         case Linear
         
-        func toControlPoints() -> (Double, Double, Double, Double) {
+        public func toControlPoints() -> (Double, Double, Double, Double) {
             switch self {
             case .Ease:
                 return (0.25, 0.1, 0.25, 0.1)

    // Hmmmmm, Actually, I don't know why the source code have samples table
    // Or it should be removed?
    private lazy var sampleValues: [Double] = {
        if self.mX1 != self.mY1 || self.mX2 != self.mY2 {
            return (0..<kSplineTableSize).map { self.calcBezier(Double($0) * kSampleStepSize, aA1: self.mX1, aA2: self.mX2) }
        } else {
            return [Double](count: kSplineTableSize, repeatedValue: 0)
        }
    }()
    
    private let mX1: Double
    private let mX2: Double
    private let mY1: Double
    private let mY2: Double
    
    public init(mX1 outerMX1: Double, mY1 outerMY1: Double, mX2 outerMX2: Double, mY2 outerMY2: Double) {
        assert((outerMX1 >= 0 && outerMX1 <= 1 && outerMX2 >= 0 && outerMX2 <= 1), "Bezier x values must be in [0, 1] range")
        
        mX1 = outerMX1
        mX2 = outerMX2
        mY1 = outerMY1
        mY2 = outerMY2
    }
    
    public init(controlPoints: (mX1: Double, mY1: Double, mX2: Double, mY2: Double)) {
        assert((controlPoints.mX1 >= 0 && controlPoints.mX1 <= 1 && controlPoints.mX2 >= 0 && controlPoints.mX2 <= 1), "Bezier x values must be in [0, 1] range")
        
        mX1 = controlPoints.mX1
        mX2 = controlPoints.mX2
        mY1 = controlPoints.mY1
        mY2 = controlPoints.mY2
    }
    
    public convenience init(easing: Easing) {

        let dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample])
        let guessForT = intervalStart + dist * kSampleStepSize
        
        let initialSlope = getSlope(guessForT, aA1: controlPoints.x1, aA2: controlPoints.x2)
        
        if initialSlope >= newtownMinSlope {
            return newtownRaphsonIterate(aX, aGuessT: guessForT, mX1: controlPoints.x1, mX2: controlPoints.x2)
        } else if initialSlope == 0 {
            return guessForT
        } else {
            return binarySubdivide(aX, aA: intervalStart, aB: intervalStart + kSampleStepSize, mX1: controlPoints.x1, mX2: controlPoints.x2)
        }
    }
    
    // MARK: - Public Methods
    public func easing(x: Double) -> Double {
        if (controlPoints.x1 == controlPoints.y1 && controlPoints.x2 == controlPoints.y2) || x == 0 || x == 1 {
            return x
        }
        
        return calcBezier(getTForX(x), aA1: controlPoints.y1, aA2: controlPoints.y2)
    }
}