//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

import CoreFoundation

internal func __NSCalendarIsAutoupdating(_ calendar: NSCalendar) -> Bool {
    return false
}

internal func __NSCalendarCurrent() -> NSCalendar {
    return CFCalendarCopyCurrent()._nsObject
}

internal func __NSCalendarInit(_ identifier: String) -> NSCalendar? {
    return NSCalendar(identifier: NSCalendar.Identifier(rawValue: identifier))
}

/**
 `Calendar` encapsulates information about systems of reckoning time in which the beginning, length, and divisions of a year are defined. It provides information about the calendar and support for calendrical computations such as determining the range of a given calendrical unit and adding units to a given absolute time.
 */
public struct Calendar : Hashable, Equatable, ReferenceConvertible, _MutableBoxing {
    public typealias ReferenceType = NSCalendar
    
    internal var _autoupdating: Bool
    internal var _handle: _MutableHandle<NSCalendar>
    
    /// Calendar supports many different kinds of calendars. Each is identified by an identifier here.
    public enum Identifier {
        /// The common calendar in Europe, the Western Hemisphere, and elsewhere.
        case gregorian
        
        case buddhist
        case chinese
        case coptic
        case ethiopicAmeteMihret
        case ethiopicAmeteAlem
        case hebrew
        case iso8601
        case indian
        case islamic
        case islamicCivil
        case japanese
        case persian
        case republicOfChina
        
        /// A simple tabular Islamic calendar using the astronomical/Thursday epoch of CE 622 July 15
        case islamicTabular
        
        /// The Islamic Umm al-Qura calendar used in Saudi Arabia. This is based on astronomical calculation, instead of tabular behavior.
        case islamicUmmAlQura
    }
    
    /// An enumeration for the various components of a calendar date.
    ///
    /// Several `Calendar` APIs use either a single unit or a set of units as input to a search algorithm.
    ///
    /// - seealso: `DateComponents`
    public enum Component {
        case era
        case year
        case month
        case day
        case hour
        case minute
        case second
        case weekday
        case weekdayOrdinal
        case quarter
        case weekOfMonth
        case weekOfYear
        case yearForWeekOfYear
        case nanosecond
        case calendar
        case timeZone
    }
    
    /// Returns the user's current calendar.
    ///
    /// This calendar does not track changes that the user makes to their preferences.
    public static var current: Calendar {
        return Calendar(adoptingReference: __NSCalendarCurrent(), autoupdating: false)
    }
    
    /// A Calendar that tracks changes to user's preferred calendar.
    ///
    /// If mutated, this calendar will no longer track the user's preferred calendar.
    ///
    /// - note: The autoupdating Calendar will only compare equal to another autoupdating Calendar.
    public static var autoupdatingCurrent: Calendar {
        // swift-corelibs-foundation does not yet support autoupdating, but we can return the current calendar (which will not change).
        return Calendar(adoptingReference: __NSCalendarCurrent(), autoupdating: true)
    }

    
    // MARK: -
    // MARK: init
    
    /// Returns a new Calendar.
    ///
    /// - parameter identifier: The kind of calendar to use.
    public init(identifier: Identifier) {
        let result = __NSCalendarInit(Calendar._toNSCalendarIdentifier(identifier).rawValue)!
        _handle = _MutableHandle(adoptingReference: result)
        _autoupdating = false
    }
    
    // MARK: -
    // MARK: Bridging
    
    internal init(reference: NSCalendar) {
        _handle = _MutableHandle(reference: reference)
        if __NSCalendarIsAutoupdating(reference) {
            _autoupdating = true
        } else {
            _autoupdating = false
        }
    }
    
    private init(adoptingReference reference: NSCalendar, autoupdating: Bool) {
        _handle = _MutableHandle(adoptingReference: reference)
        _autoupdating = autoupdating
    }
    
    // MARK: -
    //
    
    /// The identifier of the calendar.
    public var identifier: Identifier {
        return Calendar._fromNSCalendarIdentifier(_handle.map({ $0.calendarIdentifier }))
    }
    
    /// The locale of the calendar.
    public var locale: Locale? {
        get {
            return _handle.map { $0.locale }
        }
        set {
            _applyMutation { $0.locale = newValue }
        }
    }
    
    /// The time zone of the calendar.
    public var timeZone: TimeZone {
        get {
            return _handle.map { $0.timeZone }
        }
        set {
            _applyMutation { $0.timeZone = newValue }
        }
    }
    
    /// The first weekday of the calendar.
    public var firstWeekday: Int {
        get {
            return _handle.map { $0.firstWeekday }
        }
        set {
            _applyMutation { $0.firstWeekday = newValue }
        }
    }
    
    /// The number of minimum days in the first week.
    public var minimumDaysInFirstWeek: Int {
        get {
            return _handle.map { $0.minimumDaysInFirstWeek }
        }
        set {
            _applyMutation { $0.minimumDaysInFirstWeek = newValue }
        }
    }
    
    /// A list of eras in this calendar, localized to the Calendar's `locale`.
    ///
    /// For example, for English in the Gregorian calendar, returns `["BC", "AD"]`.
    ///
    /// - note: By default, Calendars have no locale set. If you wish to receive a localized answer, be sure to set the `locale` property first - most likely to `Locale.autoupdatingCurrent`.
    public var eraSymbols: [String] {
        return _handle.map { $0.eraSymbols }
    }
    
    /// A list of longer-named eras in this calendar, localized to the Calendar's `locale`.
    ///
    /// For example, for English in the Gregorian calendar, returns `["Before Christ", "Anno Domini"]`.
    ///
    /// - note: By default, Calendars have no locale set. If you wish to receive a localized answer, be sure to set the `locale` property first - most likely to `Locale.autoupdatingCurrent`.
    public var longEraSymbols: [String] {
        return _handle.map { $0.longEraSymbols }
    }
    
    /// A list of months in this calendar, localized to the Calendar's `locale`.
    ///
    /// For example, for English in the Gregorian calendar, returns `["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]`.
    ///
    /// - note: By default, Calendars have no locale set. If you wish to receive a localized answer, be sure to set the `locale` property first - most likely to `Locale.autoupdatingCurrent`.
    public var monthSymbols: [String] {
        return _handle.map { $0.monthSymbols }
    }
    
    /// A list of shorter-named months in this calendar, localized to the Calendar's `locale`.
    ///
    /// For example, for English in the Gregorian calendar, returns `["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]`.
    ///
    /// - note: By default, Calendars have no locale set. If you wish to receive a localized answer, be sure to set the `locale` property first - most likely to `Locale.autoupdatingCurrent`.
    public var shortMonthSymbols: [String] {
        return _handle.map { $0.shortMonthSymbols }
    }
    
    /// A list of very-shortly-named months in this calendar, localized to the Calendar's `locale`.
    ///
    /// For example, for English in the Gregorian calendar, returns `["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"]`.
    ///
    /// - note: By default, Calendars have no locale set. If you wish to receive a localized answer, be sure to set the `locale` property first - most likely to `Locale.autoupdatingCurrent`.
    public var veryShortMonthSymbols: [String] {
        return _handle.map { $0.veryShortMonthSymbols }
    }
    
    /// A list of standalone months in this calendar, localized to the Calendar's `locale`.
    ///
    /// For example, for English in the Gregorian calendar, returns `["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]`.
    /// - note: Stand-alone properties are for use in places like calendar headers. Non-stand-alone properties are for use in context (for example, "Saturday, November 12th").
    /// - note: By default, Calendars have no locale set. If you wish to receive a localized answer, be sure to set the `locale` property first - most likely to `Locale.autoupdatingCurrent`.
    public var standaloneMonthSymbols: [String] {
        return _handle.map { $0.standaloneMonthSymbols }
    }
    
    /// A list of shorter-named standalone months in this calendar, localized to the Calendar's `locale`.
    ///
    /// For example, for English in the Gregorian calendar, returns `["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]`.
    /// - note: Stand-alone properties are for use in places like calendar headers. Non-stand-alone properties are for use in context (for example, "Saturday, November 12th").
    /// - note: By default, Calendars have no locale set. If you wish to receive a localized answer, be sure to set the `locale` property first - most likely to `Locale.autoupdatingCurrent`.
    public var shortStandaloneMonthSymbols: [String] {
        return _handle.map { $0.shortStandaloneMonthSymbols }
    }
    
    /// A list of very-shortly-named standalone months in this calendar, localized to the Calendar's `locale`.
    ///
    /// For example, for English in the Gregorian calendar, returns `["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"]`.
    /// - note: Stand-alone properties are for use in places like calendar headers. Non-stand-alone properties are for use in context (for example, "Saturday, November 12th").
    /// - note: By default, Calendars have no locale set. If you wish to receive a localized answer, be sure to set the `locale` property first - most likely to `Locale.autoupdatingCurrent`.
    public var veryShortStandaloneMonthSymbols: [String] {
        return _handle.map { $0.veryShortStandaloneMonthSymbols }
    }
    
    /// A list of weekdays in this calendar, localized to the Calendar's `locale`.
    ///
    /// For example, for English in the Gregorian calendar, returns `["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]`.
    ///
    /// - note: By default, Calendars have no locale set. If you wish to receive a localized answer, be sure to set the `locale` property first - most likely to `Locale.autoupdatingCurrent`.
    public var weekdaySymbols: [String] {
        return _handle.map { $0.weekdaySymbols }
    }
    
    /// A list of shorter-named weekdays in this calendar, localized to the Calendar's `locale`.
    ///
    /// For example, for English in the Gregorian calendar, returns `["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]`.
    ///
    /// - note: By default, Calendars have no locale set. If you wish to receive a localized answer, be sure to set the `locale` property first - most likely to `Locale.autoupdatingCurrent`.
    public var shortWeekdaySymbols: [String] {
        return _handle.map { $0.shortWeekdaySymbols }
    }
    
    /// A list of very-shortly-named weekdays in this calendar, localized to the Calendar's `locale`.
    ///
    /// For example, for English in the Gregorian calendar, returns `["S", "M", "T", "W", "T", "F", "S"]`.
    ///
    /// - note: By default, Calendars have no locale set. If you wish to receive a localized answer, be sure to set the `locale` property first - most likely to `Locale.autoupdatingCurrent`.
    public var veryShortWeekdaySymbols: [String] {
        return _handle.map { $0.veryShortWeekdaySymbols }
    }
    
    /// A list of standalone weekday names in this calendar, localized to the Calendar's `locale`.
    ///
    /// For example, for English in the Gregorian calendar, returns `["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]`.
    /// - note: Stand-alone properties are for use in places like calendar headers. Non-stand-alone properties are for use in context (for example, "Saturday, November 12th").
    /// - note: By default, Calendars have no locale set. If you wish to receive a localized answer, be sure to set the `locale` property first - most likely to `Locale.autoupdatingCurrent`.
    public var standaloneWeekdaySymbols: [String] {
        return _handle.map { $0.standaloneWeekdaySymbols }
    }
    
    /// A list of shorter-named standalone weekdays in this calendar, localized to the Calendar's `locale`.
    ///
    /// For example, for English in the Gregorian calendar, returns `["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]`.
    /// - note: Stand-alone properties are for use in places like calendar headers. Non-stand-alone properties are for use in context (for example, "Saturday, November 12th").
    /// - note: By default, Calendars have no locale set. If you wish to receive a localized answer, be sure to set the `locale` property first - most likely to `Locale.autoupdatingCurrent`.
    public var shortStandaloneWeekdaySymbols: [String] {
        return _handle.map { $0.shortStandaloneWeekdaySymbols }
    }
    
    /// A list of very-shortly-named weekdays in this calendar, localized to the Calendar's `locale`.
    ///
    /// For example, for English in the Gregorian calendar, returns `["S", "M", "T", "W", "T", "F", "S"]`.
    /// - note: Stand-alone properties are for use in places like calendar headers. Non-stand-alone properties are for use in context (for example, "Saturday, November 12th").
    /// - note: By default, Calendars have no locale set. If you wish to receive a localized answer, be sure to set the `locale` property first - most likely to `Locale.autoupdatingCurrent`.
    public var veryShortStandaloneWeekdaySymbols: [String] {
        return _handle.map { $0.veryShortStandaloneWeekdaySymbols }
    }
    
    /// A list of quarter names in this calendar, localized to the Calendar's `locale`.
    ///
    /// For example, for English in the Gregorian calendar, returns `["1st quarter", "2nd quarter", "3rd quarter", "4th quarter"]`.
    ///
    /// - note: By default, Calendars have no locale set. If you wish to receive a localized answer, be sure to set the `locale` property first - most likely to `Locale.autoupdatingCurrent`.
    public var quarterSymbols: [String] {
        return _handle.map { $0.quarterSymbols }
    }
    
    /// A list of shorter-named quarters in this calendar, localized to the Calendar's `locale`.
    ///
    /// For example, for English in the Gregorian calendar, returns `["Q1", "Q2", "Q3", "Q4"]`.
    ///
    /// - note: By default, Calendars have no locale set. If you wish to receive a localized answer, be sure to set the `locale` property first - most likely to `Locale.autoupdatingCurrent`.
    public var shortQuarterSymbols: [String] {
        return _handle.map { $0.shortQuarterSymbols }
    }
    
    /// A list of standalone quarter names in this calendar, localized to the Calendar's `locale`.
    ///
    /// For example, for English in the Gregorian calendar, returns `["1st quarter", "2nd quarter", "3rd quarter", "4th quarter"]`.
    /// - note: Stand-alone properties are for use in places like calendar headers. Non-stand-alone properties are for use in context (for example, "Saturday, November 12th").
    /// - note: By default, Calendars have no locale set. If you wish to receive a localized answer, be sure to set the `locale` property first - most likely to `Locale.autoupdatingCurrent`.
    public var standaloneQuarterSymbols: [String] {
        return _handle.map { $0.standaloneQuarterSymbols }
    }
    
    /// A list of shorter-named standalone quarters in this calendar, localized to the Calendar's `locale`.
    ///
    /// For example, for English in the Gregorian calendar, returns `["Q1", "Q2", "Q3", "Q4"]`.
    /// - note: Stand-alone properties are for use in places like calendar headers. Non-stand-alone properties are for use in context (for example, "Saturday, November 12th").
    /// - note: By default, Calendars have no locale set. If you wish to receive a localized answer, be sure to set the `locale` property first - most likely to `Locale.autoupdatingCurrent`.
    public var shortStandaloneQuarterSymbols: [String] {
        return _handle.map { $0.shortStandaloneQuarterSymbols }
    }
    
    /// The symbol used to represent "AM", localized to the Calendar's `locale`.
    ///
    /// For example, for English in the Gregorian calendar, returns `"AM"`.
    ///
    /// - note: By default, Calendars have no locale set. If you wish to receive a localized answer, be sure to set the `locale` property first - most likely to `Locale.autoupdatingCurrent`.
    public var amSymbol: String {
        return _handle.map { $0.amSymbol }
    }
    
    /// The symbol used to represent "PM", localized to the Calendar's `locale`.
    ///
    /// For example, for English in the Gregorian calendar, returns `"PM"`.
    ///
    /// - note: By default, Calendars have no locale set. If you wish to receive a localized answer, be sure to set the `locale` property first - most likely to `Locale.autoupdatingCurrent`.
    public var pmSymbol: String {
        return _handle.map { $0.pmSymbol }
    }
    
    // MARK: -
    //
    
    /// Returns the minimum range limits of the values that a given component can take on in the receiver.
    ///
    /// As an example, in the Gregorian calendar the minimum range of values for the Day component is 1-28.
    /// - parameter component: A component to calculate a range for.
    /// - returns: The range, or nil if it could not be calculated.
    public func minimumRange(of component: Component) -> Range<Int>? {
        return _handle.map { Range($0.minimumRange(of: Calendar._toCalendarUnit([component]))) }
    }
    
    /// The maximum range limits of the values that a given component can take on in the receive
    ///
    /// As an example, in the Gregorian calendar the maximum range of values for the Day component is 1-31.
    /// - parameter component: A component to calculate a range for.
    /// - returns: The range, or nil if it could not be calculated.
    public func maximumRange(of component: Component) -> Range<Int>? {
        return _handle.map { Range($0.maximumRange(of: Calendar._toCalendarUnit([component]))) }
    }
    
    
    @available(*, unavailable, message: "use range(of:in:for:) instead")
    public func range(of smaller: NSCalendar.Unit, in larger: NSCalendar.Unit, for date: Date) -> NSRange {
        fatalError()
    }
    
    /// Returns the range of absolute time values that a smaller calendar component (such as a day) can take on in a larger calendar component (such as a month) that includes a specified absolute time.
    ///
    /// You can use this method to calculate, for example, the range the `day` component can take on in the `month` in which `date` lies.
    /// - parameter smaller: The smaller calendar component.
    /// - parameter larger: The larger calendar component.
    /// - parameter date: The absolute time for which the calculation is performed.
    /// - returns: The range of absolute time values smaller can take on in larger at the time specified by date. Returns `nil` if larger is not logically bigger than smaller in the calendar, or the given combination of components does not make sense (or is a computation which is undefined).
    public func range(of smaller: Component, in larger: Component, for date: Date) -> Range<Int>? {
        return _handle.map { Range($0.range(of: Calendar._toCalendarUnit([smaller]), in: Calendar._toCalendarUnit([larger]), for: date)) }
    }
    
    /// Returns, via two inout parameters, the starting time and duration of a given calendar component that contains a given date.
    ///
    /// - seealso: `range(of:for:)`
    /// - seealso: `dateInterval(of:for:)`
    /// - parameter component: A calendar component.
    /// - parameter start: Upon return, the starting time of the calendar component that contains the date.
    /// - parameter interval: Upon return, the duration of the calendar component that contains the date.
    /// - parameter date: The specified date.
    /// - returns: `true` if the starting time and duration of a component could be calculated, otherwise `false`.
    public func dateInterval(of component: Component, start: inout Date, interval: inout TimeInterval, for date: Date) -> Bool {
        if let result = _handle.map({ $0.range(of: Calendar._toCalendarUnit([component]), for: date)}) {
            start = result.start
            interval = result.duration
            return true
        } else {
            return false
        }
    }
    
    /// Returns the starting time and duration of a given calendar component that contains a given date.
    ///
    /// - parameter component: A calendar component.
    /// - parameter date: The specified date.
    /// - returns: A new `DateInterval` if the starting time and duration of a component could be calculated, otherwise `nil`.
    public func dateInterval(of component: Component, for date: Date) -> DateInterval? {
        var start: Date = Date(timeIntervalSinceReferenceDate: 0)
        var interval: TimeInterval = 0
        if self.dateInterval(of: component, start: &start, interval: &interval, for: date) {
            return DateInterval(start: start, duration: interval)
        } else {
            return nil
        }
    }
    
    /// Returns, for a given absolute time, the ordinal number of a smaller calendar component (such as a day) within a specified larger calendar component (such as a week).
    ///
    /// The ordinality is in most cases not the same as the decomposed value of the component. Typically return values are 1 and greater. For example, the time 00:45 is in the first hour of the day, and for components `hour` and `day` respectively, the result would be 1. An exception is the week-in-month calculation, which returns 0 for days before the first week in the month containing the date.
    ///
    /// - note: Some computations can take a relatively long time.
    /// - parameter smaller: The smaller calendar component.
    /// - parameter larger: The larger calendar component.
    /// - parameter date: The absolute time for which the calculation is performed.
    /// - returns: The ordinal number of smaller within larger at the time specified by date. Returns `nil` if larger is not logically bigger than smaller in the calendar, or the given combination of components does not make sense (or is a computation which is undefined).
    public func ordinality(of smaller: Component, in larger: Component, for date: Date) -> Int? {
        let result = _handle.map { $0.ordinality(of: Calendar._toCalendarUnit([smaller]), in: Calendar._toCalendarUnit([larger]), for: date) }
        if result == NSNotFound { return nil }
        return result
    }
    
    // MARK: -
    //
    
    @available(*, unavailable, message: "use dateComponents(_:from:) instead")
    public func getEra(_ eraValuePointer: UnsafeMutablePointer<Int>?, year yearValuePointer: UnsafeMutablePointer<Int>?, month monthValuePointer: UnsafeMutablePointer<Int>?, day dayValuePointer: UnsafeMutablePointer<Int>?, from date: Date) { fatalError() }
    
    @available(*, unavailable, message: "use dateComponents(_:from:) instead")
    public func getEra(_ eraValuePointer: UnsafeMutablePointer<Int>?, yearForWeekOfYear yearValuePointer: UnsafeMutablePointer<Int>?, weekOfYear weekValuePointer: UnsafeMutablePointer<Int>?, weekday weekdayValuePointer: UnsafeMutablePointer<Int>?, from date: Date) { fatalError() }
    
    @available(*, unavailable, message: "use dateComponents(_:from:) instead")
    public func getHour(_ hourValuePointer: UnsafeMutablePointer<Int>?, minute minuteValuePointer: UnsafeMutablePointer<Int>?, second secondValuePointer: UnsafeMutablePointer<Int>?, nanosecond nanosecondValuePointer: UnsafeMutablePointer<Int>?, from date: Date) { fatalError() }
    
    // MARK: -
    //
    
    
    @available(*, unavailable, message: "use date(byAdding:to:wrappingComponents:) instead")
    public func date(byAdding unit: NSCalendar.Unit, value: Int, to date: Date, options: NSCalendar.Options = []) -> Date? { fatalError() }
    
    /// Returns a new `Date` representing the date calculated by adding components to a given date.
    ///
    /// - parameter components: A set of values to add to the date.
    /// - parameter date: The starting date.
    /// - parameter wrappingComponents: If `true`, the component should be incremented and wrap around to zero/one on overflow, and should not cause higher components to be incremented. The default value is `false`.
    /// - returns: A new date, or nil if a date could not be calculated with the given input.
    public func date(byAdding components: DateComponents, to date: Date, wrappingComponents: Bool = false) -> Date? {
        return _handle.map { $0.date(byAdding: components, to: date, options: wrappingComponents ? [.wrapComponents] : []) }
    }
    
    
    @available(*, unavailable, message: "use date(byAdding:to:wrappingComponents:) instead")
    public func date(byAdding comps: DateComponents, to date: Date, options opts: NSCalendar.Options = []) -> Date? { fatalError() }
    
    /// Returns a new `Date` representing the date calculated by adding an amount of a specific component to a given date.
    ///
    /// - parameter component: A single component to add.
    /// - parameter value: The value of the specified component to add.
    /// - parameter date: The starting date.
    /// - parameter wrappingComponents: If `true`, the component should be incremented and wrap around to zero/one on overflow, and should not cause higher components to be incremented. The default value is `false`.
    /// - returns: A new date, or nil if a date could not be calculated with the given input.
    public func date(byAdding component: Component, value: Int, to date: Date, wrappingComponents: Bool = false) -> Date? {
        return _handle.map { $0.date(byAdding: Calendar._toCalendarUnit([component]), value: value, to: date, options: wrappingComponents ? [.wrapComponents] : []) }
    }
    
    /// Returns a date created from the specified components.
    ///
    /// - parameter components: Used as input to the search algorithm for finding a corresponding date.
    /// - returns: A new `Date`, or nil if a date could not be found which matches the components.
    public func date(from components: DateComponents) -> Date? {
        return _handle.map { $0.date(from: components) }
    }
    
    @available(*, unavailable, renamed: "dateComponents(_:from:)")
    public func components(_ unitFlags: NSCalendar.Unit, from date: Date) -> DateComponents { fatalError() }
    
    /// Returns all the date components of a date, using the calendar time zone.
    ///
    /// - note: If you want "date information in a given time zone" in order to display it, you should use `DateFormatter` to format the date.
    /// - parameter date: The `Date` to use.
    /// - returns: The date components of the specified date.
    public func dateComponents(_ components: Set<Component>, from date: Date) -> DateComponents {
        return _handle.map { $0.components(Calendar._toCalendarUnit(components), from: date) }
    }
    
    
    @available(*, unavailable, renamed: "dateComponents(in:from:)")
    public func components(in timezone: TimeZone, from date: Date) -> DateComponents { fatalError() }
    
    /// Returns all the date components of a date, as if in a given time zone (instead of the `Calendar` time zone).
    ///
    /// The time zone overrides the time zone of the `Calendar` for the purposes of this calculation.
    /// - note: If you want "date information in a given time zone" in order to display it, you should use `DateFormatter` to format the date.
    /// - parameter timeZone: The `TimeZone` to use.
    /// - parameter date: The `Date` to use.
    /// - returns: All components, calculated using the `Calendar` and `TimeZone`.
    public func dateComponents(in timeZone: TimeZone, from date: Date) -> DateComponents {
        return _handle.map { $0.components(in: timeZone, from: date) }
    }
    
    @available(*, unavailable, renamed: "dateComponents(_:from:to:)")
    public func components(_ unitFlags: NSCalendar.Unit, from startingDate: Date, to resultDate: Date, options opts: NSCalendar.Options = []) -> DateComponents { fatalError() }
    
    /// Returns the difference between two dates.
    ///
    /// - parameter components: Which components to compare.
    /// - parameter start: The starting date.
    /// - parameter end: The ending date.
    /// - returns: The result of calculating the difference from start to end.
    public func dateComponents(_ components: Set<Component>, from start: Date, to end: Date) -> DateComponents {
        return _handle.map { $0.components(Calendar._toCalendarUnit(components), from: start, to: end, options: []) }
    }
    
    @available(*, unavailable, renamed: "dateComponents(_:from:to:)")
    public func components(_ unitFlags: NSCalendar.Unit, from startingDateComp: DateComponents, to resultDateComp: DateComponents, options: NSCalendar.Options = []) -> DateComponents { fatalError() }
    
    /// Returns the difference between two dates specified as `DateComponents`.
    ///
    /// For components which are not specified in each `DateComponents`, but required to specify an absolute date, the base value of the component is assumed.  For example, for an `DateComponents` with just a `year` and a `month` specified, a `day` of 1, and an `hour`, `minute`, `second`, and `nanosecond` of 0 are assumed.
    /// Calendrical calculations with unspecified `year` or `year` value prior to the start of a calendar are not advised.
    /// For each `DateComponents`, if its `timeZone` property is set, that time zone is used for it. If the `calendar` property is set, that is used rather than the receiving calendar, and if both the `calendar` and `timeZone` are set, the `timeZone` property value overrides the time zone of the `calendar` property.
    ///
    /// - parameter components: Which components to compare.
    /// - parameter start: The starting date components.
    /// - parameter end: The ending date components.
    /// - returns: The result of calculating the difference from start to end.
    public func dateComponents(_ components: Set<Component>, from start: DateComponents, to end: DateComponents) -> DateComponents {
        return _handle.map { $0.components(Calendar._toCalendarUnit(components), from: start, to: end, options: []) }
    }
    
    
    /// Returns the value for one component of a date.
    ///
    /// - parameter component: The component to calculate.
    /// - parameter date: The date to use.
    /// - returns: The value for the component.
    public func component(_ component: Component, from date: Date) -> Int {
        return _handle.map { $0.component(Calendar._toCalendarUnit([component]), from: date) }
    }
    
    
    @available(*, unavailable, message: "Use date(from:) instead")
    public func date(era: Int, year: Int, month: Int, day: Int, hour: Int, minute: Int, second: Int, nanosecond: Int) -> Date? { fatalError() }
    
    
    @available(*, unavailable, message: "Use date(from:) instead")
    public func date(era: Int, yearForWeekOfYear: Int, weekOfYear: Int, weekday: Int, hour: Int, minute: Int, second: Int, nanosecond: Int) -> Date? { fatalError() }
    
    
    /// Returns the first moment of a given Date, as a Date.
    ///
    /// For example, pass in `Date()`, if you want the start of today.
    /// If there were two midnights, it returns the first.  If there was none, it returns the first moment that did exist.
    /// - parameter date: The date to search.
    /// - returns: The first moment of the given date.
    public func startOfDay(for date: Date) -> Date {
        return _handle.map { $0.startOfDay(for: date) }
    }
    
    
    @available(*, unavailable, renamed: "compare(_:to:toGranularity:)")
    public func compare(_ date1: Date, to date2: Date, toUnitGranularity unit: NSCalendar.Unit) -> ComparisonResult { fatalError() }
    
    
    /// Compares the given dates down to the given component, reporting them `orderedSame` if they are the same in the given component and all larger components, otherwise either `orderedAscending` or `orderedDescending`.
    ///
    /// - parameter date1: A date to compare.
    /// - parameter date2: A date to compare.
    /// - parameter component: A granularity to compare. For example, pass `.hour` to check if two dates are in the same hour.
    public func compare(_ date1: Date, to date2: Date, toGranularity component: Component) -> ComparisonResult {
        return _handle.map { $0.compare(date1, to: date2, toUnitGranularity: Calendar._toCalendarUnit([component])) }
    }
    
    
    @available(*, unavailable, renamed: "isDate(_:equalTo:toGranularity:)")
    public func isDate(_ date1: Date, equalTo date2: Date, toUnitGranularity unit: NSCalendar.Unit) -> Bool { fatalError() }
    
    /// Compares the given dates down to the given component, reporting them equal if they are the same in the given component and all larger components.
    ///
    /// - parameter date1: A date to compare.
    /// - parameter date2: A date to compare.
    /// - parameter component: A granularity to compare. For example, pass `.hour` to check if two dates are in the same hour.
    /// - returns: `true` if the given date is within tomorrow.
    public func isDate(_ date1: Date, equalTo date2: Date, toGranularity component: Component) -> Bool {
        return _handle.map { $0.isDate(date1, equalTo: date2, toUnitGranularity: Calendar._toCalendarUnit([component])) }
    }
    
    
    /// Returns `true` if the given date is within the same day as another date, as defined by the calendar and calendar's locale.
    ///
    /// - parameter date1: A date to check for containment.
    /// - parameter date2: A date to check for containment.
    /// - returns: `true` if `date1` and `date2` are in the same day.
    public func isDate(_ date1: Date, inSameDayAs date2: Date) -> Bool {
        return _handle.map { $0.isDate(date1, inSameDayAs: date2) }
    }
    
    
    /// Returns `true` if the given date is within today, as defined by the calendar and calendar's locale.
    ///
    /// - parameter date: The specified date.
    /// - returns: `true` if the given date is within today.
    public func isDateInToday(_ date: Date) -> Bool {
        return _handle.map { $0.isDateInToday(date) }
    }
    
    
    /// Returns `true` if the given date is within yesterday, as defined by the calendar and calendar's locale.
    ///
    /// - parameter date: The specified date.
    /// - returns: `true` if the given date is within yesterday.
    public func isDateInYesterday(_ date: Date) -> Bool {
        return _handle.map { $0.isDateInYesterday(date) }
    }
    
    
    /// Returns `true` if the given date is within tomorrow, as defined by the calendar and calendar's locale.
    ///
    /// - parameter date: The specified date.
    /// - returns: `true` if the given date is within tomorrow.
    public func isDateInTomorrow(_ date: Date) -> Bool {
        return _handle.map { $0.isDateInTomorrow(date) }
    }
    
    
    /// Returns `true` if the given date is within a weekend period, as defined by the calendar and calendar's locale.
    ///
    /// - parameter date: The specified date.
    /// - returns: `true` if the given date is within a weekend.
    public func isDateInWeekend(_ date: Date) -> Bool {
        return _handle.map { $0.isDateInWeekend(date) }
    }
    

    /// Find the range of the weekend around the given date, returned via two by-reference parameters.
    ///
    /// Note that a given entire day within a calendar is not necessarily all in a weekend or not; weekends can start in the middle of a day in some calendars and locales.
    /// - seealso: `dateIntervalOfWeekend(containing:)`
    /// - parameter date: The date at which to start the search.
    /// - parameter start: When the result is `true`, set
    /// - returns: `true` if a date range could be found, and `false` if the date is not in a weekend.
    public func dateIntervalOfWeekend(containing date: Date, start: inout Date, interval: inout TimeInterval) -> Bool {
        if let result = _handle.map({ $0.range(ofWeekendContaining: date) }) {
            start = result.start
            interval = result.duration
            return true
        } else {
            return false
        }
    }
    
    /// Returns a `DateInterval` of the weekend contained by the given date, or nil if the date is not in a weekend.
    ///
    /// - parameter date: The date contained in the weekend.
    /// - returns: A `DateInterval`, or nil if the date is not in a weekend.
    public func dateIntervalOfWeekend(containing date: Date) -> DateInterval? {
        return _handle.map({ $0.range(ofWeekendContaining: date) })
    }
    
    /// Returns the range of the next weekend via two inout parameters. The weekend starts strictly after the given date.
    ///
    /// If `direction` is `.backward`, then finds the previous weekend range strictly before the given date.
    ///
    /// Note that a given entire Day within a calendar is not necessarily all in a weekend or not; weekends can start in the middle of a day in some calendars and locales.
    /// - parameter date: The date at which to begin the search.
    /// - parameter direction: Which direction in time to search. The default value is `.forward`.
    /// - returns: A `DateInterval`, or nil if the weekend could not be found.
    public func nextWeekend(startingAfter date: Date, start: inout Date, interval: inout TimeInterval, direction: SearchDirection = .forward) -> Bool {
        // The implementation actually overrides previousKeepSmaller and nextKeepSmaller with matchNext, always - but strict still trumps all.
        if let result = _handle.map({ $0.nextWeekendAfter(date, options: direction == .backward ? [.searchBackwards] : []) }) {
            start = result.start
            interval = result.duration
            return true
        } else {
            return false
        }
    }
    
    /// Returns a `DateInterval` of the next weekend, which starts strictly after the given date.
    ///
    /// If `direction` is `.backward`, then finds the previous weekend range strictly before the given date.
    ///
    /// Note that a given entire Day within a calendar is not necessarily all in a weekend or not; weekends can start in the middle of a day in some calendars and locales.
    /// - parameter date: The date at which to begin the search.
    /// - parameter direction: Which direction in time to search. The default value is `.forward`.
    /// - returns: A `DateInterval`, or nil if weekends do not exist in the specific calendar or locale.
    public func nextWeekend(startingAfter date: Date, direction: SearchDirection = .forward) -> DateInterval? {
        // The implementation actually overrides previousKeepSmaller and nextKeepSmaller with matchNext, always - but strict still trumps all.
        return _handle.map({ $0.nextWeekendAfter(date, options: direction == .backward ? [.searchBackwards] : []) })
    }
    
    // MARK: -
    // MARK: Searching
    
    /// The direction in time to search.
    public enum SearchDirection {
        /// Search for a date later in time than the start date.
        case forward
        
        /// Search for a date earlier in time than the start date.
        case backward
    }
    
    /// Determines which result to use when a time is repeated on a day in a calendar (for example, during a daylight saving transition when the times between 2:00am and 3:00am may happen twice).
    public enum RepeatedTimePolicy {
        /// If there are two or more matching times (all the components are the same, including isLeapMonth) before the end of the next instance of the next higher component to the highest specified component, then the algorithm will return the first occurrence.
        case first
        
        /// If there are two or more matching times (all the components are the same, including isLeapMonth) before the end of the next instance of the next higher component to the highest specified component, then the algorithm will return the last occurrence.
        case last
    }
    
    /// A hint to the search algorithm to control the method used for searching for dates.
    public enum MatchingPolicy {
        /// If there is no matching time before the end of the next instance of the next higher component to the highest specified component in the `DateComponents` argument, the algorithm will return the next existing time which exists.
        ///
        /// For example, during a daylight saving transition there may be no 2:37am. The result would then be 3:00am, if that does exist.
        case nextTime
        
        /// If specified, and there is no matching time before the end of the next instance of the next higher component to the highest specified component in the `DateComponents` argument, the method will return the next existing value of the missing component and preserves the lower components' values (e.g., no 2:37am results in 3:37am, if that exists).
        case nextTimePreservingSmallerComponents
        
        /// If there is no matching time before the end of the next instance of the next higher component to the highest specified component in the `DateComponents` argument, the algorithm will return the previous existing value of the missing component and preserves the lower components' values.
        ///
        /// For example, during a daylight saving transition there may be no 2:37am. The result would then be 1:37am, if that does exist.
        case previousTimePreservingSmallerComponents
        
        /// If specified, the algorithm travels as far forward or backward as necessary looking for a match.
        ///
        /// For example, if searching for Feb 29 in the Gregorian calendar, the algorithm may choose March 1 instead (for example, if the year is not a leap year). If you wish to find the next Feb 29 without the algorithm adjusting the next higher component in the specified `DateComponents`, then use the `strict` option.
        /// - note: There are ultimately implementation-defined limits in how far distant the search will go.
        case strict
    }
    
    @available(*, unavailable, message: "use nextWeekend(startingAfter:matching:matchingPolicy:repeatedTimePolicy:direction:using:) instead")
    public func enumerateDates(startingAfter start: Date, matching comps: DateComponents, options opts: NSCalendar.Options = [], using block: (Date?, Bool, UnsafeMutablePointer<ObjCBool>) -> Swift.Void) {
        fatalError()
    }
    
    /// Computes the dates which match (or most closely match) a given set of components, and calls the closure once for each of them, until the enumeration is stopped.
    ///
    /// There will be at least one intervening date which does not match all the components (or the given date itself must not match) between the given date and any result.
    ///
    /// If `direction` is set to `.backward`, this method finds the previous match before the given date. The intent is that the same matches as for a `.forward` search will be found (that is, if you are enumerating forwards or backwards for each hour with minute "27", the seconds in the date you will get in forwards search would obviously be 00, and the same will be true in a backwards search in order to implement this rule.  Similarly for DST backwards jumps which repeats times, you'll get the first match by default, where "first" is defined from the point of view of searching forwards.  So, when searching backwards looking for a particular hour, with no minute and second specified, you don't get a minute and second of 59:59 for the matching hour (which would be the nominal first match within a given hour, given the other rules here, when searching backwards).
    ///
    /// If an exact match is not possible, and requested with the `strict` option, nil is passed to the closure and the enumeration ends.  (Logically, since an exact match searches indefinitely into the future, if no match is found there's no point in continuing the enumeration.)
    ///
    /// Result dates have an integer number of seconds (as if 0 was specified for the nanoseconds property of the `DateComponents` matching parameter), unless a value was set in the nanoseconds property, in which case the result date will have that number of nanoseconds (or as close as possible with floating point numbers).
    ///
    /// The enumeration is stopped by setting `stop` to `true` in the closure and returning. It is not necessary to set `stop` to `false` to keep the enumeration going.
    /// - parameter start: The `Date` at which to start the search.
    /// - parameter components: The `DateComponents` to use as input to the search algorithm.
    /// - parameter matchingPolicy: Determines the behavior of the search algorithm when the input produces an ambiguous result.
    /// - parameter repeatedTimePolicy: Determines the behavior of the search algorithm when the input produces a time that occurs twice on a particular day.
    /// - parameter direction: Which direction in time to search. The default value is `.forward`, which means later in time.
    /// - parameter block: A closure that is called with search results.
    public func enumerateDates(startingAfter start: Date, matching components: DateComponents, matchingPolicy: MatchingPolicy, repeatedTimePolicy: RepeatedTimePolicy = .first, direction: SearchDirection = .forward, using block: (_ result: Date?, _ exactMatch: Bool, _ stop: inout Bool) -> Void) {
        _handle.map {
            $0.enumerateDates(startingAfter: start, matching: components, options: Calendar._toCalendarOptions(matchingPolicy: matchingPolicy, repeatedTimePolicy: repeatedTimePolicy, direction: direction)) { (result, exactMatch, stop) in
                var stopv = false
                block(result, exactMatch, &stopv)
                if stopv {
                    stop.pointee = true
                }
            }
        }
    }
    
    
    @available(*, unavailable, message: "use nextDate(after:matching:matchingPolicy:repeatedTimePolicy:direction:) instead")
    public func nextDate(after date: Date, matching comps: DateComponents, options: NSCalendar.Options = []) -> Date? { fatalError() }
    
    /// Computes the next date which matches (or most closely matches) a given set of components.
    ///
    /// The general semantics follow those of the `enumerateDates` function.
    /// To compute a sequence of results, use the `enumerateDates` function, rather than looping and calling this method with the previous loop iteration's result.
    /// - parameter date: The starting date.
    /// - parameter components: The components to search for.
    /// - parameter matchingPolicy: Specifies the technique the search algorithm uses to find results. Default value is `.nextTime`.
    /// - parameter repeatedTimePolicy: Specifies the behavior when multiple matches are found. Default value is `.first`.
    /// - parameter direction: Specifies the direction in time to search. Default is `.forward`.
    /// - returns: A `Date` representing the result of the search, or `nil` if a result could not be found.
    public func nextDate(after date: Date, matching components: DateComponents, matchingPolicy: MatchingPolicy, repeatedTimePolicy: RepeatedTimePolicy = .first, direction: SearchDirection = .forward) -> Date? {
        return _handle.map { $0.nextDate(after: date, matching: components, options: Calendar._toCalendarOptions(matchingPolicy: matchingPolicy, repeatedTimePolicy: repeatedTimePolicy, direction: direction)) }
    }
    
    @available(*, unavailable, message: "use nextDate(after:matching:matchingPolicy:repeatedTimePolicy:direction:) instead")
    public func nextDate(after date: Date, matchingHour hourValue: Int, minute minuteValue: Int, second secondValue: Int, options: NSCalendar.Options = []) -> Date? { fatalError() }
    
    // MARK: -
    //
    
    @available(*, unavailable, renamed: "date(bySetting:value:of:)")
    public func date(bySettingUnit unit: NSCalendar.Unit, value v: Int, of date: Date, options opts: NSCalendar.Options = []) -> Date? { fatalError() }
    
    /// Returns a new `Date` representing the date calculated by setting a specific component to a given time, and trying to keep lower components the same.  If the component already has that value, this may result in a date which is the same as the given date.
    ///
    /// Changing a component's value often will require higher or coupled components to change as well.  For example, setting the Weekday to Thursday usually will require the Day component to change its value, and possibly the Month and Year as well.
    /// If no such time exists, the next available time is returned (which could, for example, be in a different day, week, month, ... than the nominal target date).  Setting a component to something which would be inconsistent forces other components to change; for example, setting the Weekday to Thursday probably shifts the Day and possibly Month and Year.
    /// The exact behavior of this method is implementation-defined. For example, if changing the weekday to Thursday, does that move forward to the next, backward to the previous, or to the nearest Thursday? The algorithm will try to produce a result which is in the next-larger component to the one given (there's a table of this mapping at the top of this document).  So for the "set to Thursday" example, find the Thursday in the Week in which the given date resides (which could be a forwards or backwards move, and not necessarily the nearest Thursday). For more control over the exact behavior, use `nextDate(after:matching:matchingPolicy:behavior:direction:)`.
    public func date(bySetting component: Component, value: Int, of date: Date) -> Date? {
        return _handle.map { $0.date(bySettingUnit: Calendar._toCalendarUnit([component]), value: value, of: date, options: []) }
    }
    
    
    @available(*, unavailable, message: "use date(bySettingHour:minute:second:of:matchingPolicy:repeatedTimePolicy:direction:) instead")
    public func date(bySettingHour h: Int, minute m: Int, second s: Int, of date: Date, options opts: NSCalendar.Options = []) -> Date? { fatalError() }
    
    /// Returns a new `Date` representing the date calculated by setting hour, minute, and second to a given time on a specified `Date`.
    ///
    /// If no such time exists, the next available time is returned (which could, for example, be in a different day than the nominal target date).
    /// The intent is to return a date on the same day as the original date argument.  This may result in a date which is backward than the given date, of course.
    /// - parameter hour: A specified hour.
    /// - parameter minute: A specified minute.
    /// - parameter second: A specified second.
    /// - parameter date: The date to start calculation with.
    /// - parameter matchingPolicy: Specifies the technique the search algorithm uses to find results. Default value is `.nextTime`.
    /// - parameter repeatedTimePolicy: Specifies the behavior when multiple matches are found. Default value is `.first`.
    /// - parameter direction: Specifies the direction in time to search. Default is `.forward`.
    /// - returns: A `Date` representing the result of the search, or `nil` if a result could not be found.
    public func date(bySettingHour hour: Int, minute: Int, second: Int, of date: Date, matchingPolicy: MatchingPolicy = .nextTime, repeatedTimePolicy: RepeatedTimePolicy = .first, direction: SearchDirection = .forward) -> Date? {
        return _handle.map { $0.date(bySettingHour: hour, minute: minute, second: second, of: date, options: Calendar._toCalendarOptions(matchingPolicy: matchingPolicy, repeatedTimePolicy: repeatedTimePolicy, direction: direction)) }
    }
    
    /// Determine if the `Date` has all of the specified `DateComponents`.
    ///
    /// It may be useful to test the return value of `nextDate(after:matching:matchingPolicy:behavior:direction:)` to find out if the components were obeyed or if the method had to fudge the result value due to missing time (for example, a daylight saving time transition).
    ///
    /// - returns: `true` if the date matches all of the components, otherwise `false`.
    public func date(_ date: Date, matchesComponents components: DateComponents) -> Bool {
        return _handle.map { $0.date(date, matchesComponents: components) }
    }
    
    // MARK: -
    
    public var hashValue: Int {
        // We implement hash ourselves, because we need to make sure autoupdating calendars have the same hash
        if _autoupdating {
            return 1
        } else {
            return _handle.map { $0.hash }
        }
    }
    
    public static func ==(lhs: Calendar, rhs: Calendar) -> Bool {
        if lhs._autoupdating || rhs._autoupdating {
            return lhs._autoupdating == rhs._autoupdating
        } else {
            // NSCalendar's isEqual is broken (27019864) so we must implement this ourselves
            return lhs.identifier == rhs.identifier &&
                lhs.locale == rhs.locale &&
                lhs.timeZone == rhs.timeZone &&
                lhs.firstWeekday == rhs.firstWeekday &&
                lhs.minimumDaysInFirstWeek == rhs.minimumDaysInFirstWeek
        }
    }
    
    // MARK: -
    // MARK: Conversion Functions
    
    /// Turn our more-specific options into the big bucket option set of NSCalendar
    internal static func _toCalendarOptions(matchingPolicy: MatchingPolicy, repeatedTimePolicy: RepeatedTimePolicy, direction: SearchDirection) -> NSCalendar.Options {
        var result: NSCalendar.Options = []
        
        switch matchingPolicy {
        case .nextTime:
            let _ = result.insert(.matchNextTime)
        case .nextTimePreservingSmallerComponents:
            let _ = result.insert(.matchNextTimePreservingSmallerUnits)
        case .previousTimePreservingSmallerComponents:
            let _ = result.insert(.matchPreviousTimePreservingSmallerUnits)
        case .strict:
            let _ = result.insert(.matchStrictly)
        }
        
        switch repeatedTimePolicy {
        case .first:
            let _ = result.insert(.matchFirst)
        case .last:
            let _ = result.insert(.matchLast)
        }
        
        switch direction {
        case .backward:
            let _ = result.insert(.searchBackwards)
        case .forward:
            break
        }
        
        return result
    }
    
    internal static func _toCalendarUnit(_ units: Set<Component>) -> NSCalendar.Unit {
        let unitMap: [Component : NSCalendar.Unit] =
            [.era: .era,
             .year: .year,
             .month: .month,
             .day: .day,
             .hour: .hour,
             .minute: .minute,
             .second: .second,
             .weekday: .weekday,
             .weekdayOrdinal: .weekdayOrdinal,
             .quarter: .quarter,
             .weekOfMonth: .weekOfMonth,
             .weekOfYear: .weekOfYear,
             .yearForWeekOfYear: .yearForWeekOfYear,
             .nanosecond: .nanosecond,
             .calendar: .calendar,
             .timeZone: .timeZone]
        
        var result = NSCalendar.Unit()
        for u in units {
            let _ = result.insert(unitMap[u]!)
        }
        return result
    }
    
    internal static func _fromCalendarUnit(_ unit: NSCalendar.Unit) -> Component {
        switch unit {
        case NSCalendar.Unit.era:
            return Component.era
        case NSCalendar.Unit.year:
            return Component.year
        case NSCalendar.Unit.month:
            return Component.month
        case NSCalendar.Unit.day:
            return Component.day
        case NSCalendar.Unit.hour:
            return Component.hour
        case NSCalendar.Unit.minute:
            return Component.minute
        case NSCalendar.Unit.second:
            return Component.second
        case NSCalendar.Unit.weekday:
            return Component.weekday
        case NSCalendar.Unit.weekdayOrdinal:
            return Component.weekdayOrdinal
        case NSCalendar.Unit.quarter:
            return Component.quarter
        case NSCalendar.Unit.weekOfMonth:
            return Component.weekOfMonth
        case NSCalendar.Unit.weekOfYear:
            return Component.weekOfYear
        case NSCalendar.Unit.yearForWeekOfYear:
            return Component.yearForWeekOfYear
        case NSCalendar.Unit.nanosecond:
            return Component.nanosecond
        case NSCalendar.Unit.calendar:
            return Component.calendar
        case NSCalendar.Unit.timeZone:
            return Component.timeZone
        default:
            fatalError()
        }
    }
    
    internal static func _fromCalendarUnits(_ units: NSCalendar.Unit) -> Set<Component> {
        var result = Set<Component>()
        if units.contains(.era) {
            result.insert(.era)
        }
        
        if units.contains(.year) {
            result.insert(.year)
        }
        
        if units.contains(.month) {
            result.insert(.month)
        }
        
        if units.contains(.day) {
            result.insert(.day)
        }

        if units.contains(.hour) {
            result.insert(.hour)
        }
        
        if units.contains(.minute) {
            result.insert(.minute)
        }
        
        if units.contains(.second) {
            result.insert(.second)
        }
        
        if units.contains(.weekday) {
            result.insert(.weekday)
        }
        
        if units.contains(.weekdayOrdinal) {
            result.insert(.weekdayOrdinal)
        }
        
        if units.contains(.quarter) {
            result.insert(.quarter)
        }
        
        if units.contains(.weekOfMonth) {
            result.insert(.weekOfMonth)
        }
        
        if units.contains(.weekOfYear) {
            result.insert(.weekOfYear)
        }
        
        if units.contains(.yearForWeekOfYear) {
            result.insert(.yearForWeekOfYear)
        }
        
        if units.contains(.nanosecond) {
            result.insert(.nanosecond)
        }
        
        if units.contains(.calendar) {
            result.insert(.calendar)
        }
        
        if units.contains(.timeZone) {
            result.insert(.timeZone)
        }
        
        return result
    }
    
    internal static func _toNSCalendarIdentifier(_ identifier: Identifier) -> NSCalendar.Identifier {
        if #available(OSX 10.10, iOS 8.0, *) {
            let identifierMap: [Identifier : NSCalendar.Identifier] =
                [.gregorian: .gregorian,
                 .buddhist: .buddhist,
                 .chinese: .chinese,
                 .coptic: .coptic,
                 .ethiopicAmeteMihret: .ethiopicAmeteMihret,
                 .ethiopicAmeteAlem: .ethiopicAmeteAlem,
                 .hebrew: .hebrew,
                 .iso8601: .ISO8601,
                 .indian: .indian,
                 .islamic: .islamic,
                 .islamicCivil: .islamicCivil,
                 .japanese: .japanese,
                 .persian: .persian,
                 .republicOfChina: .republicOfChina,
                 .islamicTabular: .islamicTabular,
                 .islamicUmmAlQura: .islamicUmmAlQura]
            return identifierMap[identifier]!
        } else {
            let identifierMap: [Identifier : NSCalendar.Identifier] =
                [.gregorian: .gregorian,
                 .buddhist: .buddhist,
                 .chinese: .chinese,
                 .coptic: .coptic,
                 .ethiopicAmeteMihret: .ethiopicAmeteMihret,
                 .ethiopicAmeteAlem: .ethiopicAmeteAlem,
                 .hebrew: .hebrew,
                 .iso8601: .ISO8601,
                 .indian: .indian,
                 .islamic: .islamic,
                 .islamicCivil: .islamicCivil,
                 .japanese: .japanese,
                 .persian: .persian,
                 .republicOfChina: .republicOfChina]
            return identifierMap[identifier]!
        }
    }
    
    internal static func _fromNSCalendarIdentifier(_ identifier: NSCalendar.Identifier) -> Identifier {
        if #available(OSX 10.10, iOS 8.0, *) {
            let identifierMap: [NSCalendar.Identifier : Identifier] =
                [.gregorian: .gregorian,
                 .buddhist: .buddhist,
                 .chinese: .chinese,
                 .coptic: .coptic,
                 .ethiopicAmeteMihret: .ethiopicAmeteMihret,
                 .ethiopicAmeteAlem: .ethiopicAmeteAlem,
                 .hebrew: .hebrew,
                 .ISO8601: .iso8601,
                 .indian: .indian,
                 .islamic: .islamic,
                 .islamicCivil: .islamicCivil,
                 .japanese: .japanese,
                 .persian: .persian,
                 .republicOfChina: .republicOfChina,
                 .islamicTabular: .islamicTabular,
                 .islamicUmmAlQura: .islamicUmmAlQura]
            return identifierMap[identifier]!
        } else {
            let identifierMap: [NSCalendar.Identifier : Identifier] =
                [.gregorian: .gregorian,
                 .buddhist: .buddhist,
                 .chinese: .chinese,
                 .coptic: .coptic,
                 .ethiopicAmeteMihret: .ethiopicAmeteMihret,
                 .ethiopicAmeteAlem: .ethiopicAmeteAlem,
                 .hebrew: .hebrew,
                 .ISO8601: .iso8601,
                 .indian: .indian,
                 .islamic: .islamic,
                 .islamicCivil: .islamicCivil,
                 .japanese: .japanese,
                 .persian: .persian,
                 .republicOfChina: .republicOfChina]
            return identifierMap[identifier]!
        }
    }
}

extension Calendar : CustomDebugStringConvertible, CustomStringConvertible, CustomReflectable {
    private var _kindDescription : String {
        if self == .autoupdatingCurrent {
            return "autoupdatingCurrent"
        } else if self == .current {
            return "current"
        } else {
            return "fixed"
        }
    }
    
    public var description: String {
        return "\(identifier) (\(_kindDescription))"
    }
    
    public var debugDescription: String {
        return "\(identifier) (\(_kindDescription))"
    }
    
    public var customMirror: Mirror {
        let children: [(label: String?, value: Any)] = [
            (label: "identifier", value: identifier),
            (label: "kind", value: _kindDescription),
            (label: "locale", value: locale as Any),
            (label: "timeZone", value: timeZone),
            (label: "firstWeekDay", value: firstWeekday),
            (label: "minimumDaysInFirstWeek", value: minimumDaysInFirstWeek)
        ]
        return Mirror(self, children: children, displayStyle: Mirror.DisplayStyle.struct)
    }
}

extension Calendar: _ObjectTypeBridgeable {
    public typealias _ObjectType = NSCalendar
    
    @_semantics("convertToObjectiveC")
    public func _bridgeToObjectiveC() -> NSCalendar {
        return _handle._copiedReference()
    }
    
    public static func _forceBridgeFromObjectiveC(_ input: NSCalendar, result: inout Calendar?) {
        if !_conditionallyBridgeFromObjectiveC(input, result: &result) {
            fatalError("Unable to bridge \(NSCalendar.self) to \(self)")
        }
    }
    
    @discardableResult
    public static func _conditionallyBridgeFromObjectiveC(_ input: NSCalendar, result: inout Calendar?) -> Bool {
        result = Calendar(reference: input)
        return true
    }
    
    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSCalendar?) -> Calendar {
        var result: Calendar? = nil
        _forceBridgeFromObjectiveC(source!, result: &result)
        return result!
    }
}

extension Calendar : Codable {
    private enum CodingKeys : Int, CodingKey {
        case identifier
        case locale
        case timeZone
        case firstWeekday
        case minimumDaysInFirstWeek
    }

    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let identifierString = try container.decode(String.self, forKey: .identifier)
        let identifier = Calendar._fromNSCalendarIdentifier(NSCalendar.Identifier(rawValue: identifierString))
        self.init(identifier: identifier)

        self.locale = try container.decodeIfPresent(Locale.self, forKey: .locale)
        self.timeZone = try container.decode(TimeZone.self, forKey: .timeZone)
        self.firstWeekday = try container.decode(Int.self, forKey: .firstWeekday)
        self.minimumDaysInFirstWeek = try container.decode(Int.self, forKey: .minimumDaysInFirstWeek)
    }

    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)

        let identifier = Calendar._toNSCalendarIdentifier(self.identifier).rawValue
        try container.encode(identifier, forKey: .identifier)
        try container.encode(self.locale, forKey: .locale)
        try container.encode(self.timeZone, forKey: .timeZone)
        try container.encode(self.firstWeekday, forKey: .firstWeekday)
        try container.encode(self.minimumDaysInFirstWeek, forKey: .minimumDaysInFirstWeek)
    }
}
