///
/// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
///
/// Auto-generated by Stone, do not modify.
///

import Foundation

/// Datatypes and serializers for the paper namespace
open class Paper {
    /// The AddMember struct
    open class AddMember: CustomStringConvertible {
        /// Permission for the user.
        public let permissionLevel: Paper.PaperDocPermissionLevel
        /// User which should be added to the Paper doc. Specify only email address or Dropbox account ID.
        public let member: Sharing.MemberSelector
        public init(member: Sharing.MemberSelector, permissionLevel: Paper.PaperDocPermissionLevel = .edit) {
            self.permissionLevel = permissionLevel
            self.member = member
        }
        open var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(AddMemberSerializer().serialize(self)))"
        }
    }
    open class AddMemberSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: AddMember) -> JSON {
            let output = [ 
            "member": Sharing.MemberSelectorSerializer().serialize(value.member),
            "permission_level": Paper.PaperDocPermissionLevelSerializer().serialize(value.permissionLevel),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> AddMember {
            switch json {
                case .dictionary(let dict):
                    let member = Sharing.MemberSelectorSerializer().deserialize(dict["member"] ?? .null)
                    let permissionLevel = Paper.PaperDocPermissionLevelSerializer().deserialize(dict["permission_level"] ?? Paper.PaperDocPermissionLevelSerializer().serialize(.edit))
                    return AddMember(member: member, permissionLevel: permissionLevel)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The RefPaperDoc struct
    open class RefPaperDoc: CustomStringConvertible {
        /// The Paper doc ID.
        public let docId: String
        public init(docId: String) {
            stringValidator()(docId)
            self.docId = docId
        }
        open var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(RefPaperDocSerializer().serialize(self)))"
        }
    }
    open class RefPaperDocSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: RefPaperDoc) -> JSON {
            let output = [ 
            "doc_id": Serialization._StringSerializer.serialize(value.docId),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> RefPaperDoc {
            switch json {
                case .dictionary(let dict):
                    let docId = Serialization._StringSerializer.deserialize(dict["doc_id"] ?? .null)
                    return RefPaperDoc(docId: docId)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The AddPaperDocUser struct
    open class AddPaperDocUser: Paper.RefPaperDoc {
        /// User which should be added to the Paper doc. Specify only email address or Dropbox account ID.
        public let members: Array<Paper.AddMember>
        /// A personal message that will be emailed to each successfully added member.
        public let customMessage: String?
        /// Clients should set this to true if no email message shall be sent to added users.
        public let quiet: Bool
        public init(docId: String, members: Array<Paper.AddMember>, customMessage: String? = nil, quiet: Bool = false) {
            self.members = members
            nullableValidator(stringValidator())(customMessage)
            self.customMessage = customMessage
            self.quiet = quiet
            super.init(docId: docId)
        }
        open override var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(AddPaperDocUserSerializer().serialize(self)))"
        }
    }
    open class AddPaperDocUserSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: AddPaperDocUser) -> JSON {
            let output = [ 
            "doc_id": Serialization._StringSerializer.serialize(value.docId),
            "members": ArraySerializer(Paper.AddMemberSerializer()).serialize(value.members),
            "custom_message": NullableSerializer(Serialization._StringSerializer).serialize(value.customMessage),
            "quiet": Serialization._BoolSerializer.serialize(value.quiet),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> AddPaperDocUser {
            switch json {
                case .dictionary(let dict):
                    let docId = Serialization._StringSerializer.deserialize(dict["doc_id"] ?? .null)
                    let members = ArraySerializer(Paper.AddMemberSerializer()).deserialize(dict["members"] ?? .null)
                    let customMessage = NullableSerializer(Serialization._StringSerializer).deserialize(dict["custom_message"] ?? .null)
                    let quiet = Serialization._BoolSerializer.deserialize(dict["quiet"] ?? .number(0))
                    return AddPaperDocUser(docId: docId, members: members, customMessage: customMessage, quiet: quiet)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// Per-member result for docsUsersAdd.
    open class AddPaperDocUserMemberResult: CustomStringConvertible {
        /// One of specified input members.
        public let member: Sharing.MemberSelector
        /// The outcome of the action on this member.
        public let result: Paper.AddPaperDocUserResult
        public init(member: Sharing.MemberSelector, result: Paper.AddPaperDocUserResult) {
            self.member = member
            self.result = result
        }
        open var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(AddPaperDocUserMemberResultSerializer().serialize(self)))"
        }
    }
    open class AddPaperDocUserMemberResultSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: AddPaperDocUserMemberResult) -> JSON {
            let output = [ 
            "member": Sharing.MemberSelectorSerializer().serialize(value.member),
            "result": Paper.AddPaperDocUserResultSerializer().serialize(value.result),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> AddPaperDocUserMemberResult {
            switch json {
                case .dictionary(let dict):
                    let member = Sharing.MemberSelectorSerializer().deserialize(dict["member"] ?? .null)
                    let result = Paper.AddPaperDocUserResultSerializer().deserialize(dict["result"] ?? .null)
                    return AddPaperDocUserMemberResult(member: member, result: result)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The AddPaperDocUserResult union
    public enum AddPaperDocUserResult: CustomStringConvertible {
        /// User was successfully added to the Paper doc.
        case success
        /// Something unexpected happened when trying to add the user to the Paper doc.
        case unknownError
        /// The Paper doc can be shared only with team members.
        case sharingOutsideTeamDisabled
        /// The daily limit of how many users can be added to the Paper doc was reached.
        case dailyLimitReached
        /// Owner's permissions cannot be changed.
        case userIsOwner
        /// User data could not be retrieved. Clients should retry.
        case failedUserDataRetrieval
        /// This user already has the correct permission to the Paper doc.
        case permissionAlreadyGranted
        /// An unspecified error.
        case other

        public var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(AddPaperDocUserResultSerializer().serialize(self)))"
        }
    }
    open class AddPaperDocUserResultSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: AddPaperDocUserResult) -> JSON {
            switch value {
                case .success:
                    var d = [String: JSON]()
                    d[".tag"] = .str("success")
                    return .dictionary(d)
                case .unknownError:
                    var d = [String: JSON]()
                    d[".tag"] = .str("unknown_error")
                    return .dictionary(d)
                case .sharingOutsideTeamDisabled:
                    var d = [String: JSON]()
                    d[".tag"] = .str("sharing_outside_team_disabled")
                    return .dictionary(d)
                case .dailyLimitReached:
                    var d = [String: JSON]()
                    d[".tag"] = .str("daily_limit_reached")
                    return .dictionary(d)
                case .userIsOwner:
                    var d = [String: JSON]()
                    d[".tag"] = .str("user_is_owner")
                    return .dictionary(d)
                case .failedUserDataRetrieval:
                    var d = [String: JSON]()
                    d[".tag"] = .str("failed_user_data_retrieval")
                    return .dictionary(d)
                case .permissionAlreadyGranted:
                    var d = [String: JSON]()
                    d[".tag"] = .str("permission_already_granted")
                    return .dictionary(d)
                case .other:
                    var d = [String: JSON]()
                    d[".tag"] = .str("other")
                    return .dictionary(d)
            }
        }
        open func deserialize(_ json: JSON) -> AddPaperDocUserResult {
            switch json {
                case .dictionary(let d):
                    let tag = Serialization.getTag(d)
                    switch tag {
                        case "success":
                            return AddPaperDocUserResult.success
                        case "unknown_error":
                            return AddPaperDocUserResult.unknownError
                        case "sharing_outside_team_disabled":
                            return AddPaperDocUserResult.sharingOutsideTeamDisabled
                        case "daily_limit_reached":
                            return AddPaperDocUserResult.dailyLimitReached
                        case "user_is_owner":
                            return AddPaperDocUserResult.userIsOwner
                        case "failed_user_data_retrieval":
                            return AddPaperDocUserResult.failedUserDataRetrieval
                        case "permission_already_granted":
                            return AddPaperDocUserResult.permissionAlreadyGranted
                        case "other":
                            return AddPaperDocUserResult.other
                        default:
                            return AddPaperDocUserResult.other
                    }
                default:
                    fatalError("Failed to deserialize")
            }
        }
    }

    /// The Cursor struct
    open class Cursor: CustomStringConvertible {
        /// The actual cursor value.
        public let value: String
        /// Expiration time of value. Some cursors might have expiration time assigned. This is a UTC value after which
        /// the cursor is no longer valid and the API starts returning an error. If cursor expires a new one needs to be
        /// obtained and pagination needs to be restarted. Some cursors might be short-lived some cursors might be
        /// long-lived. This really depends on the sorting type and order, e.g.: 1. on one hand, listing docs created by
        /// the user, sorted by the created time ascending will have undefinite expiration because the results cannot
        /// change while the iteration is happening. This cursor would be suitable for long term polling. 2. on the
        /// other hand, listing docs sorted by the last modified time will have a very short expiration as docs do get
        /// modified very often and the modified time can be changed while the iteration is happening thus altering the
        /// results.
        public let expiration: Date?
        public init(value: String, expiration: Date? = nil) {
            stringValidator()(value)
            self.value = value
            self.expiration = expiration
        }
        open var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(CursorSerializer().serialize(self)))"
        }
    }
    open class CursorSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: Cursor) -> JSON {
            let output = [ 
            "value": Serialization._StringSerializer.serialize(value.value),
            "expiration": NullableSerializer(NSDateSerializer("%Y-%m-%dT%H:%M:%SZ")).serialize(value.expiration),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> Cursor {
            switch json {
                case .dictionary(let dict):
                    let value = Serialization._StringSerializer.deserialize(dict["value"] ?? .null)
                    let expiration = NullableSerializer(NSDateSerializer("%Y-%m-%dT%H:%M:%SZ")).deserialize(dict["expiration"] ?? .null)
                    return Cursor(value: value, expiration: expiration)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The PaperApiBaseError union
    public enum PaperApiBaseError: CustomStringConvertible {
        /// Your account does not have permissions to perform this action.
        case insufficientPermissions
        /// An unspecified error.
        case other

        public var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(PaperApiBaseErrorSerializer().serialize(self)))"
        }
    }
    open class PaperApiBaseErrorSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: PaperApiBaseError) -> JSON {
            switch value {
                case .insufficientPermissions:
                    var d = [String: JSON]()
                    d[".tag"] = .str("insufficient_permissions")
                    return .dictionary(d)
                case .other:
                    var d = [String: JSON]()
                    d[".tag"] = .str("other")
                    return .dictionary(d)
            }
        }
        open func deserialize(_ json: JSON) -> PaperApiBaseError {
            switch json {
                case .dictionary(let d):
                    let tag = Serialization.getTag(d)
                    switch tag {
                        case "insufficient_permissions":
                            return PaperApiBaseError.insufficientPermissions
                        case "other":
                            return PaperApiBaseError.other
                        default:
                            return PaperApiBaseError.other
                    }
                default:
                    fatalError("Failed to deserialize")
            }
        }
    }

    /// The DocLookupError union
    public enum DocLookupError: CustomStringConvertible {
        /// Your account does not have permissions to perform this action.
        case insufficientPermissions
        /// An unspecified error.
        case other
        /// The required doc was not found.
        case docNotFound

        public var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(DocLookupErrorSerializer().serialize(self)))"
        }
    }
    open class DocLookupErrorSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: DocLookupError) -> JSON {
            switch value {
                case .insufficientPermissions:
                    var d = [String: JSON]()
                    d[".tag"] = .str("insufficient_permissions")
                    return .dictionary(d)
                case .other:
                    var d = [String: JSON]()
                    d[".tag"] = .str("other")
                    return .dictionary(d)
                case .docNotFound:
                    var d = [String: JSON]()
                    d[".tag"] = .str("doc_not_found")
                    return .dictionary(d)
            }
        }
        open func deserialize(_ json: JSON) -> DocLookupError {
            switch json {
                case .dictionary(let d):
                    let tag = Serialization.getTag(d)
                    switch tag {
                        case "insufficient_permissions":
                            return DocLookupError.insufficientPermissions
                        case "other":
                            return DocLookupError.other
                        case "doc_not_found":
                            return DocLookupError.docNotFound
                        default:
                            fatalError("Unknown tag \(tag)")
                    }
                default:
                    fatalError("Failed to deserialize")
            }
        }
    }

    /// The subscription level of a Paper doc.
    public enum DocSubscriptionLevel: CustomStringConvertible {
        /// No change email messages unless you're the creator.
        case default_
        /// Ignored: Not shown in pad lists or activity and no email message is sent.
        case ignore
        /// Subscribed: Shown in pad lists and activity and change email messages are sent.
        case every
        /// Unsubscribed: Shown in pad lists, but not in activity and no change email messages are sent.
        case noEmail

        public var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(DocSubscriptionLevelSerializer().serialize(self)))"
        }
    }
    open class DocSubscriptionLevelSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: DocSubscriptionLevel) -> JSON {
            switch value {
                case .default_:
                    var d = [String: JSON]()
                    d[".tag"] = .str("default")
                    return .dictionary(d)
                case .ignore:
                    var d = [String: JSON]()
                    d[".tag"] = .str("ignore")
                    return .dictionary(d)
                case .every:
                    var d = [String: JSON]()
                    d[".tag"] = .str("every")
                    return .dictionary(d)
                case .noEmail:
                    var d = [String: JSON]()
                    d[".tag"] = .str("no_email")
                    return .dictionary(d)
            }
        }
        open func deserialize(_ json: JSON) -> DocSubscriptionLevel {
            switch json {
                case .dictionary(let d):
                    let tag = Serialization.getTag(d)
                    switch tag {
                        case "default":
                            return DocSubscriptionLevel.default_
                        case "ignore":
                            return DocSubscriptionLevel.ignore
                        case "every":
                            return DocSubscriptionLevel.every
                        case "no_email":
                            return DocSubscriptionLevel.noEmail
                        default:
                            fatalError("Unknown tag \(tag)")
                    }
                default:
                    fatalError("Failed to deserialize")
            }
        }
    }

    /// The desired export format of the Paper doc.
    public enum ExportFormat: CustomStringConvertible {
        /// The HTML export format.
        case html
        /// The markdown export format.
        case markdown
        /// An unspecified error.
        case other

        public var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(ExportFormatSerializer().serialize(self)))"
        }
    }
    open class ExportFormatSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: ExportFormat) -> JSON {
            switch value {
                case .html:
                    var d = [String: JSON]()
                    d[".tag"] = .str("html")
                    return .dictionary(d)
                case .markdown:
                    var d = [String: JSON]()
                    d[".tag"] = .str("markdown")
                    return .dictionary(d)
                case .other:
                    var d = [String: JSON]()
                    d[".tag"] = .str("other")
                    return .dictionary(d)
            }
        }
        open func deserialize(_ json: JSON) -> ExportFormat {
            switch json {
                case .dictionary(let d):
                    let tag = Serialization.getTag(d)
                    switch tag {
                        case "html":
                            return ExportFormat.html
                        case "markdown":
                            return ExportFormat.markdown
                        case "other":
                            return ExportFormat.other
                        default:
                            return ExportFormat.other
                    }
                default:
                    fatalError("Failed to deserialize")
            }
        }
    }

    /// Data structure representing a Paper folder.
    open class Folder: CustomStringConvertible {
        /// Paper folder ID. This ID uniquely identifies the folder.
        public let id: String
        /// Paper folder name.
        public let name: String
        public init(id: String, name: String) {
            stringValidator()(id)
            self.id = id
            stringValidator()(name)
            self.name = name
        }
        open var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(FolderSerializer().serialize(self)))"
        }
    }
    open class FolderSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: Folder) -> JSON {
            let output = [ 
            "id": Serialization._StringSerializer.serialize(value.id),
            "name": Serialization._StringSerializer.serialize(value.name),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> Folder {
            switch json {
                case .dictionary(let dict):
                    let id = Serialization._StringSerializer.deserialize(dict["id"] ?? .null)
                    let name = Serialization._StringSerializer.deserialize(dict["name"] ?? .null)
                    return Folder(id: id, name: name)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The sharing policy of a Paper folder.  Note: The sharing policy of subfolders is inherited from the root folder.
    public enum FolderSharingPolicyType: CustomStringConvertible {
        /// Everyone in your team and anyone directly invited can access this folder.
        case team
        /// Only people directly invited can access this folder.
        case inviteOnly

        public var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(FolderSharingPolicyTypeSerializer().serialize(self)))"
        }
    }
    open class FolderSharingPolicyTypeSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: FolderSharingPolicyType) -> JSON {
            switch value {
                case .team:
                    var d = [String: JSON]()
                    d[".tag"] = .str("team")
                    return .dictionary(d)
                case .inviteOnly:
                    var d = [String: JSON]()
                    d[".tag"] = .str("invite_only")
                    return .dictionary(d)
            }
        }
        open func deserialize(_ json: JSON) -> FolderSharingPolicyType {
            switch json {
                case .dictionary(let d):
                    let tag = Serialization.getTag(d)
                    switch tag {
                        case "team":
                            return FolderSharingPolicyType.team
                        case "invite_only":
                            return FolderSharingPolicyType.inviteOnly
                        default:
                            fatalError("Unknown tag \(tag)")
                    }
                default:
                    fatalError("Failed to deserialize")
            }
        }
    }

    /// The subscription level of a Paper folder.
    public enum FolderSubscriptionLevel: CustomStringConvertible {
        /// Not shown in activity, no email messages.
        case none
        /// Shown in activity, no email messages.
        case activityOnly
        /// Shown in activity, daily email messages.
        case dailyEmails
        /// Shown in activity, weekly email messages.
        case weeklyEmails

        public var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(FolderSubscriptionLevelSerializer().serialize(self)))"
        }
    }
    open class FolderSubscriptionLevelSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: FolderSubscriptionLevel) -> JSON {
            switch value {
                case .none:
                    var d = [String: JSON]()
                    d[".tag"] = .str("none")
                    return .dictionary(d)
                case .activityOnly:
                    var d = [String: JSON]()
                    d[".tag"] = .str("activity_only")
                    return .dictionary(d)
                case .dailyEmails:
                    var d = [String: JSON]()
                    d[".tag"] = .str("daily_emails")
                    return .dictionary(d)
                case .weeklyEmails:
                    var d = [String: JSON]()
                    d[".tag"] = .str("weekly_emails")
                    return .dictionary(d)
            }
        }
        open func deserialize(_ json: JSON) -> FolderSubscriptionLevel {
            switch json {
                case .dictionary(let d):
                    let tag = Serialization.getTag(d)
                    switch tag {
                        case "none":
                            return FolderSubscriptionLevel.none
                        case "activity_only":
                            return FolderSubscriptionLevel.activityOnly
                        case "daily_emails":
                            return FolderSubscriptionLevel.dailyEmails
                        case "weekly_emails":
                            return FolderSubscriptionLevel.weeklyEmails
                        default:
                            fatalError("Unknown tag \(tag)")
                    }
                default:
                    fatalError("Failed to deserialize")
            }
        }
    }

    /// Metadata about Paper folders containing the specififed Paper doc.
    open class FoldersContainingPaperDoc: CustomStringConvertible {
        /// The sharing policy of the folder containing the Paper doc.
        public let folderSharingPolicyType: Paper.FolderSharingPolicyType?
        /// The folder path. If present the first folder is the root folder.
        public let folders: Array<Paper.Folder>?
        public init(folderSharingPolicyType: Paper.FolderSharingPolicyType? = nil, folders: Array<Paper.Folder>? = nil) {
            self.folderSharingPolicyType = folderSharingPolicyType
            self.folders = folders
        }
        open var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(FoldersContainingPaperDocSerializer().serialize(self)))"
        }
    }
    open class FoldersContainingPaperDocSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: FoldersContainingPaperDoc) -> JSON {
            let output = [ 
            "folder_sharing_policy_type": NullableSerializer(Paper.FolderSharingPolicyTypeSerializer()).serialize(value.folderSharingPolicyType),
            "folders": NullableSerializer(ArraySerializer(Paper.FolderSerializer())).serialize(value.folders),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> FoldersContainingPaperDoc {
            switch json {
                case .dictionary(let dict):
                    let folderSharingPolicyType = NullableSerializer(Paper.FolderSharingPolicyTypeSerializer()).deserialize(dict["folder_sharing_policy_type"] ?? .null)
                    let folders = NullableSerializer(ArraySerializer(Paper.FolderSerializer())).deserialize(dict["folders"] ?? .null)
                    return FoldersContainingPaperDoc(folderSharingPolicyType: folderSharingPolicyType, folders: folders)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The import format of the incoming data.
    public enum ImportFormat: CustomStringConvertible {
        /// The provided data is interpreted as standard HTML.
        case html
        /// The provided data is interpreted as markdown. Note: The first line of the provided document will be used as
        /// the doc title.
        case markdown
        /// The provided data is interpreted as plain text. Note: The first line of the provided document will be used
        /// as the doc title.
        case plainText
        /// An unspecified error.
        case other

        public var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(ImportFormatSerializer().serialize(self)))"
        }
    }
    open class ImportFormatSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: ImportFormat) -> JSON {
            switch value {
                case .html:
                    var d = [String: JSON]()
                    d[".tag"] = .str("html")
                    return .dictionary(d)
                case .markdown:
                    var d = [String: JSON]()
                    d[".tag"] = .str("markdown")
                    return .dictionary(d)
                case .plainText:
                    var d = [String: JSON]()
                    d[".tag"] = .str("plain_text")
                    return .dictionary(d)
                case .other:
                    var d = [String: JSON]()
                    d[".tag"] = .str("other")
                    return .dictionary(d)
            }
        }
        open func deserialize(_ json: JSON) -> ImportFormat {
            switch json {
                case .dictionary(let d):
                    let tag = Serialization.getTag(d)
                    switch tag {
                        case "html":
                            return ImportFormat.html
                        case "markdown":
                            return ImportFormat.markdown
                        case "plain_text":
                            return ImportFormat.plainText
                        case "other":
                            return ImportFormat.other
                        default:
                            return ImportFormat.other
                    }
                default:
                    fatalError("Failed to deserialize")
            }
        }
    }

    /// The InviteeInfoWithPermissionLevel struct
    open class InviteeInfoWithPermissionLevel: CustomStringConvertible {
        /// Email address invited to the Paper doc.
        public let invitee: Sharing.InviteeInfo
        /// Permission level for the invitee.
        public let permissionLevel: Paper.PaperDocPermissionLevel
        public init(invitee: Sharing.InviteeInfo, permissionLevel: Paper.PaperDocPermissionLevel) {
            self.invitee = invitee
            self.permissionLevel = permissionLevel
        }
        open var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(InviteeInfoWithPermissionLevelSerializer().serialize(self)))"
        }
    }
    open class InviteeInfoWithPermissionLevelSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: InviteeInfoWithPermissionLevel) -> JSON {
            let output = [ 
            "invitee": Sharing.InviteeInfoSerializer().serialize(value.invitee),
            "permission_level": Paper.PaperDocPermissionLevelSerializer().serialize(value.permissionLevel),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> InviteeInfoWithPermissionLevel {
            switch json {
                case .dictionary(let dict):
                    let invitee = Sharing.InviteeInfoSerializer().deserialize(dict["invitee"] ?? .null)
                    let permissionLevel = Paper.PaperDocPermissionLevelSerializer().deserialize(dict["permission_level"] ?? .null)
                    return InviteeInfoWithPermissionLevel(invitee: invitee, permissionLevel: permissionLevel)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The ListDocsCursorError union
    public enum ListDocsCursorError: CustomStringConvertible {
        /// An unspecified error.
        case cursorError(Paper.PaperApiCursorError)
        /// An unspecified error.
        case other

        public var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(ListDocsCursorErrorSerializer().serialize(self)))"
        }
    }
    open class ListDocsCursorErrorSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: ListDocsCursorError) -> JSON {
            switch value {
                case .cursorError(let arg):
                    var d = ["cursor_error": Paper.PaperApiCursorErrorSerializer().serialize(arg)]
                    d[".tag"] = .str("cursor_error")
                    return .dictionary(d)
                case .other:
                    var d = [String: JSON]()
                    d[".tag"] = .str("other")
                    return .dictionary(d)
            }
        }
        open func deserialize(_ json: JSON) -> ListDocsCursorError {
            switch json {
                case .dictionary(let d):
                    let tag = Serialization.getTag(d)
                    switch tag {
                        case "cursor_error":
                            let v = Paper.PaperApiCursorErrorSerializer().deserialize(d["cursor_error"] ?? .null)
                            return ListDocsCursorError.cursorError(v)
                        case "other":
                            return ListDocsCursorError.other
                        default:
                            return ListDocsCursorError.other
                    }
                default:
                    fatalError("Failed to deserialize")
            }
        }
    }

    /// The ListPaperDocsArgs struct
    open class ListPaperDocsArgs: CustomStringConvertible {
        /// Allows user to specify how the Paper docs should be filtered.
        public let filterBy: Paper.ListPaperDocsFilterBy
        /// Allows user to specify how the Paper docs should be sorted.
        public let sortBy: Paper.ListPaperDocsSortBy
        /// Allows user to specify the sort order of the result.
        public let sortOrder: Paper.ListPaperDocsSortOrder
        /// Size limit per batch. The maximum number of docs that can be retrieved per batch is 1000. Higher value
        /// results in invalid arguments error.
        public let limit: Int32
        public init(filterBy: Paper.ListPaperDocsFilterBy = .docsAccessed, sortBy: Paper.ListPaperDocsSortBy = .accessed, sortOrder: Paper.ListPaperDocsSortOrder = .ascending, limit: Int32 = 1000) {
            self.filterBy = filterBy
            self.sortBy = sortBy
            self.sortOrder = sortOrder
            comparableValidator(minValue: 1, maxValue: 1000)(limit)
            self.limit = limit
        }
        open var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(ListPaperDocsArgsSerializer().serialize(self)))"
        }
    }
    open class ListPaperDocsArgsSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: ListPaperDocsArgs) -> JSON {
            let output = [ 
            "filter_by": Paper.ListPaperDocsFilterBySerializer().serialize(value.filterBy),
            "sort_by": Paper.ListPaperDocsSortBySerializer().serialize(value.sortBy),
            "sort_order": Paper.ListPaperDocsSortOrderSerializer().serialize(value.sortOrder),
            "limit": Serialization._Int32Serializer.serialize(value.limit),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> ListPaperDocsArgs {
            switch json {
                case .dictionary(let dict):
                    let filterBy = Paper.ListPaperDocsFilterBySerializer().deserialize(dict["filter_by"] ?? Paper.ListPaperDocsFilterBySerializer().serialize(.docsAccessed))
                    let sortBy = Paper.ListPaperDocsSortBySerializer().deserialize(dict["sort_by"] ?? Paper.ListPaperDocsSortBySerializer().serialize(.accessed))
                    let sortOrder = Paper.ListPaperDocsSortOrderSerializer().deserialize(dict["sort_order"] ?? Paper.ListPaperDocsSortOrderSerializer().serialize(.ascending))
                    let limit = Serialization._Int32Serializer.deserialize(dict["limit"] ?? .number(1000))
                    return ListPaperDocsArgs(filterBy: filterBy, sortBy: sortBy, sortOrder: sortOrder, limit: limit)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The ListPaperDocsContinueArgs struct
    open class ListPaperDocsContinueArgs: CustomStringConvertible {
        /// The cursor obtained from docsList or docsListContinue. Allows for pagination.
        public let cursor: String
        public init(cursor: String) {
            stringValidator()(cursor)
            self.cursor = cursor
        }
        open var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(ListPaperDocsContinueArgsSerializer().serialize(self)))"
        }
    }
    open class ListPaperDocsContinueArgsSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: ListPaperDocsContinueArgs) -> JSON {
            let output = [ 
            "cursor": Serialization._StringSerializer.serialize(value.cursor),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> ListPaperDocsContinueArgs {
            switch json {
                case .dictionary(let dict):
                    let cursor = Serialization._StringSerializer.deserialize(dict["cursor"] ?? .null)
                    return ListPaperDocsContinueArgs(cursor: cursor)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The ListPaperDocsFilterBy union
    public enum ListPaperDocsFilterBy: CustomStringConvertible {
        /// Fetches all Paper doc IDs that the user has ever accessed.
        case docsAccessed
        /// Fetches only the Paper doc IDs that the user has created.
        case docsCreated
        /// An unspecified error.
        case other

        public var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(ListPaperDocsFilterBySerializer().serialize(self)))"
        }
    }
    open class ListPaperDocsFilterBySerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: ListPaperDocsFilterBy) -> JSON {
            switch value {
                case .docsAccessed:
                    var d = [String: JSON]()
                    d[".tag"] = .str("docs_accessed")
                    return .dictionary(d)
                case .docsCreated:
                    var d = [String: JSON]()
                    d[".tag"] = .str("docs_created")
                    return .dictionary(d)
                case .other:
                    var d = [String: JSON]()
                    d[".tag"] = .str("other")
                    return .dictionary(d)
            }
        }
        open func deserialize(_ json: JSON) -> ListPaperDocsFilterBy {
            switch json {
                case .dictionary(let d):
                    let tag = Serialization.getTag(d)
                    switch tag {
                        case "docs_accessed":
                            return ListPaperDocsFilterBy.docsAccessed
                        case "docs_created":
                            return ListPaperDocsFilterBy.docsCreated
                        case "other":
                            return ListPaperDocsFilterBy.other
                        default:
                            return ListPaperDocsFilterBy.other
                    }
                default:
                    fatalError("Failed to deserialize")
            }
        }
    }

    /// The ListPaperDocsResponse struct
    open class ListPaperDocsResponse: CustomStringConvertible {
        /// The list of Paper doc IDs that can be used to access the given Paper docs or supplied to other API methods.
        /// The list is sorted in the order specified by the initial call to docsList.
        public let docIds: Array<String>
        /// Pass the cursor into docsListContinue to paginate through all files. The cursor preserves all properties as
        /// specified in the original call to docsList.
        public let cursor: Paper.Cursor
        /// Will be set to True if a subsequent call with the provided cursor to docsListContinue returns immediately
        /// with some results. If set to False please allow some delay before making another call to docsListContinue.
        public let hasMore: Bool
        public init(docIds: Array<String>, cursor: Paper.Cursor, hasMore: Bool) {
            arrayValidator(itemValidator: stringValidator())(docIds)
            self.docIds = docIds
            self.cursor = cursor
            self.hasMore = hasMore
        }
        open var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(ListPaperDocsResponseSerializer().serialize(self)))"
        }
    }
    open class ListPaperDocsResponseSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: ListPaperDocsResponse) -> JSON {
            let output = [ 
            "doc_ids": ArraySerializer(Serialization._StringSerializer).serialize(value.docIds),
            "cursor": Paper.CursorSerializer().serialize(value.cursor),
            "has_more": Serialization._BoolSerializer.serialize(value.hasMore),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> ListPaperDocsResponse {
            switch json {
                case .dictionary(let dict):
                    let docIds = ArraySerializer(Serialization._StringSerializer).deserialize(dict["doc_ids"] ?? .null)
                    let cursor = Paper.CursorSerializer().deserialize(dict["cursor"] ?? .null)
                    let hasMore = Serialization._BoolSerializer.deserialize(dict["has_more"] ?? .null)
                    return ListPaperDocsResponse(docIds: docIds, cursor: cursor, hasMore: hasMore)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The ListPaperDocsSortBy union
    public enum ListPaperDocsSortBy: CustomStringConvertible {
        /// Sorts the Paper docs by the time they were last accessed.
        case accessed
        /// Sorts the Paper docs by the time they were last modified.
        case modified
        /// Sorts the Paper docs by the creation time.
        case created
        /// An unspecified error.
        case other

        public var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(ListPaperDocsSortBySerializer().serialize(self)))"
        }
    }
    open class ListPaperDocsSortBySerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: ListPaperDocsSortBy) -> JSON {
            switch value {
                case .accessed:
                    var d = [String: JSON]()
                    d[".tag"] = .str("accessed")
                    return .dictionary(d)
                case .modified:
                    var d = [String: JSON]()
                    d[".tag"] = .str("modified")
                    return .dictionary(d)
                case .created:
                    var d = [String: JSON]()
                    d[".tag"] = .str("created")
                    return .dictionary(d)
                case .other:
                    var d = [String: JSON]()
                    d[".tag"] = .str("other")
                    return .dictionary(d)
            }
        }
        open func deserialize(_ json: JSON) -> ListPaperDocsSortBy {
            switch json {
                case .dictionary(let d):
                    let tag = Serialization.getTag(d)
                    switch tag {
                        case "accessed":
                            return ListPaperDocsSortBy.accessed
                        case "modified":
                            return ListPaperDocsSortBy.modified
                        case "created":
                            return ListPaperDocsSortBy.created
                        case "other":
                            return ListPaperDocsSortBy.other
                        default:
                            return ListPaperDocsSortBy.other
                    }
                default:
                    fatalError("Failed to deserialize")
            }
        }
    }

    /// The ListPaperDocsSortOrder union
    public enum ListPaperDocsSortOrder: CustomStringConvertible {
        /// Sorts the search result in ascending order.
        case ascending
        /// Sorts the search result in descending order.
        case descending
        /// An unspecified error.
        case other

        public var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(ListPaperDocsSortOrderSerializer().serialize(self)))"
        }
    }
    open class ListPaperDocsSortOrderSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: ListPaperDocsSortOrder) -> JSON {
            switch value {
                case .ascending:
                    var d = [String: JSON]()
                    d[".tag"] = .str("ascending")
                    return .dictionary(d)
                case .descending:
                    var d = [String: JSON]()
                    d[".tag"] = .str("descending")
                    return .dictionary(d)
                case .other:
                    var d = [String: JSON]()
                    d[".tag"] = .str("other")
                    return .dictionary(d)
            }
        }
        open func deserialize(_ json: JSON) -> ListPaperDocsSortOrder {
            switch json {
                case .dictionary(let d):
                    let tag = Serialization.getTag(d)
                    switch tag {
                        case "ascending":
                            return ListPaperDocsSortOrder.ascending
                        case "descending":
                            return ListPaperDocsSortOrder.descending
                        case "other":
                            return ListPaperDocsSortOrder.other
                        default:
                            return ListPaperDocsSortOrder.other
                    }
                default:
                    fatalError("Failed to deserialize")
            }
        }
    }

    /// The ListUsersCursorError union
    public enum ListUsersCursorError: CustomStringConvertible {
        /// Your account does not have permissions to perform this action.
        case insufficientPermissions
        /// An unspecified error.
        case other
        /// The required doc was not found.
        case docNotFound
        /// An unspecified error.
        case cursorError(Paper.PaperApiCursorError)

        public var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(ListUsersCursorErrorSerializer().serialize(self)))"
        }
    }
    open class ListUsersCursorErrorSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: ListUsersCursorError) -> JSON {
            switch value {
                case .insufficientPermissions:
                    var d = [String: JSON]()
                    d[".tag"] = .str("insufficient_permissions")
                    return .dictionary(d)
                case .other:
                    var d = [String: JSON]()
                    d[".tag"] = .str("other")
                    return .dictionary(d)
                case .docNotFound:
                    var d = [String: JSON]()
                    d[".tag"] = .str("doc_not_found")
                    return .dictionary(d)
                case .cursorError(let arg):
                    var d = ["cursor_error": Paper.PaperApiCursorErrorSerializer().serialize(arg)]
                    d[".tag"] = .str("cursor_error")
                    return .dictionary(d)
            }
        }
        open func deserialize(_ json: JSON) -> ListUsersCursorError {
            switch json {
                case .dictionary(let d):
                    let tag = Serialization.getTag(d)
                    switch tag {
                        case "insufficient_permissions":
                            return ListUsersCursorError.insufficientPermissions
                        case "other":
                            return ListUsersCursorError.other
                        case "doc_not_found":
                            return ListUsersCursorError.docNotFound
                        case "cursor_error":
                            let v = Paper.PaperApiCursorErrorSerializer().deserialize(d["cursor_error"] ?? .null)
                            return ListUsersCursorError.cursorError(v)
                        default:
                            fatalError("Unknown tag \(tag)")
                    }
                default:
                    fatalError("Failed to deserialize")
            }
        }
    }

    /// The ListUsersOnFolderArgs struct
    open class ListUsersOnFolderArgs: Paper.RefPaperDoc {
        /// Size limit per batch. The maximum number of users that can be retrieved per batch is 1000. Higher value
        /// results in invalid arguments error.
        public let limit: Int32
        public init(docId: String, limit: Int32 = 1000) {
            comparableValidator(minValue: 1, maxValue: 1000)(limit)
            self.limit = limit
            super.init(docId: docId)
        }
        open override var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(ListUsersOnFolderArgsSerializer().serialize(self)))"
        }
    }
    open class ListUsersOnFolderArgsSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: ListUsersOnFolderArgs) -> JSON {
            let output = [ 
            "doc_id": Serialization._StringSerializer.serialize(value.docId),
            "limit": Serialization._Int32Serializer.serialize(value.limit),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> ListUsersOnFolderArgs {
            switch json {
                case .dictionary(let dict):
                    let docId = Serialization._StringSerializer.deserialize(dict["doc_id"] ?? .null)
                    let limit = Serialization._Int32Serializer.deserialize(dict["limit"] ?? .number(1000))
                    return ListUsersOnFolderArgs(docId: docId, limit: limit)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The ListUsersOnFolderContinueArgs struct
    open class ListUsersOnFolderContinueArgs: Paper.RefPaperDoc {
        /// The cursor obtained from docsFolderUsersList or docsFolderUsersListContinue. Allows for pagination.
        public let cursor: String
        public init(docId: String, cursor: String) {
            stringValidator()(cursor)
            self.cursor = cursor
            super.init(docId: docId)
        }
        open override var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(ListUsersOnFolderContinueArgsSerializer().serialize(self)))"
        }
    }
    open class ListUsersOnFolderContinueArgsSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: ListUsersOnFolderContinueArgs) -> JSON {
            let output = [ 
            "doc_id": Serialization._StringSerializer.serialize(value.docId),
            "cursor": Serialization._StringSerializer.serialize(value.cursor),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> ListUsersOnFolderContinueArgs {
            switch json {
                case .dictionary(let dict):
                    let docId = Serialization._StringSerializer.deserialize(dict["doc_id"] ?? .null)
                    let cursor = Serialization._StringSerializer.deserialize(dict["cursor"] ?? .null)
                    return ListUsersOnFolderContinueArgs(docId: docId, cursor: cursor)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The ListUsersOnFolderResponse struct
    open class ListUsersOnFolderResponse: CustomStringConvertible {
        /// List of email addresses that are invited on the Paper folder.
        public let invitees: Array<Sharing.InviteeInfo>
        /// List of users that are invited on the Paper folder.
        public let users: Array<Sharing.UserInfo>
        /// Pass the cursor into docsFolderUsersListContinue to paginate through all users. The cursor preserves all
        /// properties as specified in the original call to docsFolderUsersList.
        public let cursor: Paper.Cursor
        /// Will be set to True if a subsequent call with the provided cursor to docsFolderUsersListContinue returns
        /// immediately with some results. If set to False please allow some delay before making another call to
        /// docsFolderUsersListContinue.
        public let hasMore: Bool
        public init(invitees: Array<Sharing.InviteeInfo>, users: Array<Sharing.UserInfo>, cursor: Paper.Cursor, hasMore: Bool) {
            self.invitees = invitees
            self.users = users
            self.cursor = cursor
            self.hasMore = hasMore
        }
        open var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(ListUsersOnFolderResponseSerializer().serialize(self)))"
        }
    }
    open class ListUsersOnFolderResponseSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: ListUsersOnFolderResponse) -> JSON {
            let output = [ 
            "invitees": ArraySerializer(Sharing.InviteeInfoSerializer()).serialize(value.invitees),
            "users": ArraySerializer(Sharing.UserInfoSerializer()).serialize(value.users),
            "cursor": Paper.CursorSerializer().serialize(value.cursor),
            "has_more": Serialization._BoolSerializer.serialize(value.hasMore),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> ListUsersOnFolderResponse {
            switch json {
                case .dictionary(let dict):
                    let invitees = ArraySerializer(Sharing.InviteeInfoSerializer()).deserialize(dict["invitees"] ?? .null)
                    let users = ArraySerializer(Sharing.UserInfoSerializer()).deserialize(dict["users"] ?? .null)
                    let cursor = Paper.CursorSerializer().deserialize(dict["cursor"] ?? .null)
                    let hasMore = Serialization._BoolSerializer.deserialize(dict["has_more"] ?? .null)
                    return ListUsersOnFolderResponse(invitees: invitees, users: users, cursor: cursor, hasMore: hasMore)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The ListUsersOnPaperDocArgs struct
    open class ListUsersOnPaperDocArgs: Paper.RefPaperDoc {
        /// Size limit per batch. The maximum number of users that can be retrieved per batch is 1000. Higher value
        /// results in invalid arguments error.
        public let limit: Int32
        /// Specify this attribute if you want to obtain users that have already accessed the Paper doc.
        public let filterBy: Paper.UserOnPaperDocFilter
        public init(docId: String, limit: Int32 = 1000, filterBy: Paper.UserOnPaperDocFilter = .shared) {
            comparableValidator(minValue: 1, maxValue: 1000)(limit)
            self.limit = limit
            self.filterBy = filterBy
            super.init(docId: docId)
        }
        open override var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(ListUsersOnPaperDocArgsSerializer().serialize(self)))"
        }
    }
    open class ListUsersOnPaperDocArgsSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: ListUsersOnPaperDocArgs) -> JSON {
            let output = [ 
            "doc_id": Serialization._StringSerializer.serialize(value.docId),
            "limit": Serialization._Int32Serializer.serialize(value.limit),
            "filter_by": Paper.UserOnPaperDocFilterSerializer().serialize(value.filterBy),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> ListUsersOnPaperDocArgs {
            switch json {
                case .dictionary(let dict):
                    let docId = Serialization._StringSerializer.deserialize(dict["doc_id"] ?? .null)
                    let limit = Serialization._Int32Serializer.deserialize(dict["limit"] ?? .number(1000))
                    let filterBy = Paper.UserOnPaperDocFilterSerializer().deserialize(dict["filter_by"] ?? Paper.UserOnPaperDocFilterSerializer().serialize(.shared))
                    return ListUsersOnPaperDocArgs(docId: docId, limit: limit, filterBy: filterBy)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The ListUsersOnPaperDocContinueArgs struct
    open class ListUsersOnPaperDocContinueArgs: Paper.RefPaperDoc {
        /// The cursor obtained from docsUsersList or docsUsersListContinue. Allows for pagination.
        public let cursor: String
        public init(docId: String, cursor: String) {
            stringValidator()(cursor)
            self.cursor = cursor
            super.init(docId: docId)
        }
        open override var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(ListUsersOnPaperDocContinueArgsSerializer().serialize(self)))"
        }
    }
    open class ListUsersOnPaperDocContinueArgsSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: ListUsersOnPaperDocContinueArgs) -> JSON {
            let output = [ 
            "doc_id": Serialization._StringSerializer.serialize(value.docId),
            "cursor": Serialization._StringSerializer.serialize(value.cursor),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> ListUsersOnPaperDocContinueArgs {
            switch json {
                case .dictionary(let dict):
                    let docId = Serialization._StringSerializer.deserialize(dict["doc_id"] ?? .null)
                    let cursor = Serialization._StringSerializer.deserialize(dict["cursor"] ?? .null)
                    return ListUsersOnPaperDocContinueArgs(docId: docId, cursor: cursor)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The ListUsersOnPaperDocResponse struct
    open class ListUsersOnPaperDocResponse: CustomStringConvertible {
        /// List of email addresses with their respective permission levels that are invited on the Paper doc.
        public let invitees: Array<Paper.InviteeInfoWithPermissionLevel>
        /// List of users with their respective permission levels that are invited on the Paper folder.
        public let users: Array<Paper.UserInfoWithPermissionLevel>
        /// The Paper doc owner. This field is populated on every single response.
        public let docOwner: Sharing.UserInfo
        /// Pass the cursor into docsUsersListContinue to paginate through all users. The cursor preserves all
        /// properties as specified in the original call to docsUsersList.
        public let cursor: Paper.Cursor
        /// Will be set to True if a subsequent call with the provided cursor to docsUsersListContinue returns
        /// immediately with some results. If set to False please allow some delay before making another call to
        /// docsUsersListContinue.
        public let hasMore: Bool
        public init(invitees: Array<Paper.InviteeInfoWithPermissionLevel>, users: Array<Paper.UserInfoWithPermissionLevel>, docOwner: Sharing.UserInfo, cursor: Paper.Cursor, hasMore: Bool) {
            self.invitees = invitees
            self.users = users
            self.docOwner = docOwner
            self.cursor = cursor
            self.hasMore = hasMore
        }
        open var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(ListUsersOnPaperDocResponseSerializer().serialize(self)))"
        }
    }
    open class ListUsersOnPaperDocResponseSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: ListUsersOnPaperDocResponse) -> JSON {
            let output = [ 
            "invitees": ArraySerializer(Paper.InviteeInfoWithPermissionLevelSerializer()).serialize(value.invitees),
            "users": ArraySerializer(Paper.UserInfoWithPermissionLevelSerializer()).serialize(value.users),
            "doc_owner": Sharing.UserInfoSerializer().serialize(value.docOwner),
            "cursor": Paper.CursorSerializer().serialize(value.cursor),
            "has_more": Serialization._BoolSerializer.serialize(value.hasMore),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> ListUsersOnPaperDocResponse {
            switch json {
                case .dictionary(let dict):
                    let invitees = ArraySerializer(Paper.InviteeInfoWithPermissionLevelSerializer()).deserialize(dict["invitees"] ?? .null)
                    let users = ArraySerializer(Paper.UserInfoWithPermissionLevelSerializer()).deserialize(dict["users"] ?? .null)
                    let docOwner = Sharing.UserInfoSerializer().deserialize(dict["doc_owner"] ?? .null)
                    let cursor = Paper.CursorSerializer().deserialize(dict["cursor"] ?? .null)
                    let hasMore = Serialization._BoolSerializer.deserialize(dict["has_more"] ?? .null)
                    return ListUsersOnPaperDocResponse(invitees: invitees, users: users, docOwner: docOwner, cursor: cursor, hasMore: hasMore)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The PaperApiCursorError union
    public enum PaperApiCursorError: CustomStringConvertible {
        /// The provided cursor is expired.
        case expiredCursor
        /// The provided cursor is invalid.
        case invalidCursor
        /// The provided cursor contains invalid user.
        case wrongUserInCursor
        /// Indicates that the cursor has been invalidated. Call the corresponding non-continue endpoint to obtain a new
        /// cursor.
        case reset
        /// An unspecified error.
        case other

        public var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(PaperApiCursorErrorSerializer().serialize(self)))"
        }
    }
    open class PaperApiCursorErrorSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: PaperApiCursorError) -> JSON {
            switch value {
                case .expiredCursor:
                    var d = [String: JSON]()
                    d[".tag"] = .str("expired_cursor")
                    return .dictionary(d)
                case .invalidCursor:
                    var d = [String: JSON]()
                    d[".tag"] = .str("invalid_cursor")
                    return .dictionary(d)
                case .wrongUserInCursor:
                    var d = [String: JSON]()
                    d[".tag"] = .str("wrong_user_in_cursor")
                    return .dictionary(d)
                case .reset:
                    var d = [String: JSON]()
                    d[".tag"] = .str("reset")
                    return .dictionary(d)
                case .other:
                    var d = [String: JSON]()
                    d[".tag"] = .str("other")
                    return .dictionary(d)
            }
        }
        open func deserialize(_ json: JSON) -> PaperApiCursorError {
            switch json {
                case .dictionary(let d):
                    let tag = Serialization.getTag(d)
                    switch tag {
                        case "expired_cursor":
                            return PaperApiCursorError.expiredCursor
                        case "invalid_cursor":
                            return PaperApiCursorError.invalidCursor
                        case "wrong_user_in_cursor":
                            return PaperApiCursorError.wrongUserInCursor
                        case "reset":
                            return PaperApiCursorError.reset
                        case "other":
                            return PaperApiCursorError.other
                        default:
                            return PaperApiCursorError.other
                    }
                default:
                    fatalError("Failed to deserialize")
            }
        }
    }

    /// The PaperDocCreateArgs struct
    open class PaperDocCreateArgs: CustomStringConvertible {
        /// The Paper folder ID where the Paper document should be created. The API user has to have write access to
        /// this folder or error is thrown.
        public let parentFolderId: String?
        /// The format of provided data.
        public let importFormat: Paper.ImportFormat
        public init(importFormat: Paper.ImportFormat, parentFolderId: String? = nil) {
            nullableValidator(stringValidator())(parentFolderId)
            self.parentFolderId = parentFolderId
            self.importFormat = importFormat
        }
        open var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(PaperDocCreateArgsSerializer().serialize(self)))"
        }
    }
    open class PaperDocCreateArgsSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: PaperDocCreateArgs) -> JSON {
            let output = [ 
            "import_format": Paper.ImportFormatSerializer().serialize(value.importFormat),
            "parent_folder_id": NullableSerializer(Serialization._StringSerializer).serialize(value.parentFolderId),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> PaperDocCreateArgs {
            switch json {
                case .dictionary(let dict):
                    let importFormat = Paper.ImportFormatSerializer().deserialize(dict["import_format"] ?? .null)
                    let parentFolderId = NullableSerializer(Serialization._StringSerializer).deserialize(dict["parent_folder_id"] ?? .null)
                    return PaperDocCreateArgs(importFormat: importFormat, parentFolderId: parentFolderId)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The PaperDocCreateError union
    public enum PaperDocCreateError: CustomStringConvertible {
        /// Your account does not have permissions to perform this action.
        case insufficientPermissions
        /// An unspecified error.
        case other
        /// The provided content was malformed and cannot be imported to Paper.
        case contentMalformed
        /// The specified Paper folder is cannot be found.
        case folderNotFound
        /// The newly created Paper doc would be too large. Please split the content into multiple docs.
        case docLengthExceeded
        /// The imported document contains an image that is too large. The current limit is 1MB. Note: This only applies
        /// to HTML with data uri.
        case imageSizeExceeded

        public var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(PaperDocCreateErrorSerializer().serialize(self)))"
        }
    }
    open class PaperDocCreateErrorSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: PaperDocCreateError) -> JSON {
            switch value {
                case .insufficientPermissions:
                    var d = [String: JSON]()
                    d[".tag"] = .str("insufficient_permissions")
                    return .dictionary(d)
                case .other:
                    var d = [String: JSON]()
                    d[".tag"] = .str("other")
                    return .dictionary(d)
                case .contentMalformed:
                    var d = [String: JSON]()
                    d[".tag"] = .str("content_malformed")
                    return .dictionary(d)
                case .folderNotFound:
                    var d = [String: JSON]()
                    d[".tag"] = .str("folder_not_found")
                    return .dictionary(d)
                case .docLengthExceeded:
                    var d = [String: JSON]()
                    d[".tag"] = .str("doc_length_exceeded")
                    return .dictionary(d)
                case .imageSizeExceeded:
                    var d = [String: JSON]()
                    d[".tag"] = .str("image_size_exceeded")
                    return .dictionary(d)
            }
        }
        open func deserialize(_ json: JSON) -> PaperDocCreateError {
            switch json {
                case .dictionary(let d):
                    let tag = Serialization.getTag(d)
                    switch tag {
                        case "insufficient_permissions":
                            return PaperDocCreateError.insufficientPermissions
                        case "other":
                            return PaperDocCreateError.other
                        case "content_malformed":
                            return PaperDocCreateError.contentMalformed
                        case "folder_not_found":
                            return PaperDocCreateError.folderNotFound
                        case "doc_length_exceeded":
                            return PaperDocCreateError.docLengthExceeded
                        case "image_size_exceeded":
                            return PaperDocCreateError.imageSizeExceeded
                        default:
                            fatalError("Unknown tag \(tag)")
                    }
                default:
                    fatalError("Failed to deserialize")
            }
        }
    }

    /// The PaperDocCreateUpdateResult struct
    open class PaperDocCreateUpdateResult: CustomStringConvertible {
        /// Doc ID of the newly created doc.
        public let docId: String
        /// The Paper doc revision. Simply an ever increasing number.
        public let revision: Int64
        /// The Paper doc title.
        public let title: String
        public init(docId: String, revision: Int64, title: String) {
            stringValidator()(docId)
            self.docId = docId
            comparableValidator()(revision)
            self.revision = revision
            stringValidator()(title)
            self.title = title
        }
        open var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(PaperDocCreateUpdateResultSerializer().serialize(self)))"
        }
    }
    open class PaperDocCreateUpdateResultSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: PaperDocCreateUpdateResult) -> JSON {
            let output = [ 
            "doc_id": Serialization._StringSerializer.serialize(value.docId),
            "revision": Serialization._Int64Serializer.serialize(value.revision),
            "title": Serialization._StringSerializer.serialize(value.title),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> PaperDocCreateUpdateResult {
            switch json {
                case .dictionary(let dict):
                    let docId = Serialization._StringSerializer.deserialize(dict["doc_id"] ?? .null)
                    let revision = Serialization._Int64Serializer.deserialize(dict["revision"] ?? .null)
                    let title = Serialization._StringSerializer.deserialize(dict["title"] ?? .null)
                    return PaperDocCreateUpdateResult(docId: docId, revision: revision, title: title)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The PaperDocExport struct
    open class PaperDocExport: Paper.RefPaperDoc {
        /// (no description)
        public let exportFormat: Paper.ExportFormat
        public init(docId: String, exportFormat: Paper.ExportFormat) {
            self.exportFormat = exportFormat
            super.init(docId: docId)
        }
        open override var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(PaperDocExportSerializer().serialize(self)))"
        }
    }
    open class PaperDocExportSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: PaperDocExport) -> JSON {
            let output = [ 
            "doc_id": Serialization._StringSerializer.serialize(value.docId),
            "export_format": Paper.ExportFormatSerializer().serialize(value.exportFormat),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> PaperDocExport {
            switch json {
                case .dictionary(let dict):
                    let docId = Serialization._StringSerializer.deserialize(dict["doc_id"] ?? .null)
                    let exportFormat = Paper.ExportFormatSerializer().deserialize(dict["export_format"] ?? .null)
                    return PaperDocExport(docId: docId, exportFormat: exportFormat)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The PaperDocExportResult struct
    open class PaperDocExportResult: CustomStringConvertible {
        /// The Paper doc owner's email address.
        public let owner: String
        /// The Paper doc title.
        public let title: String
        /// The Paper doc revision. Simply an ever increasing number.
        public let revision: Int64
        /// MIME type of the export. This corresponds to ExportFormat specified in the request.
        public let mimeType: String
        public init(owner: String, title: String, revision: Int64, mimeType: String) {
            stringValidator()(owner)
            self.owner = owner
            stringValidator()(title)
            self.title = title
            comparableValidator()(revision)
            self.revision = revision
            stringValidator()(mimeType)
            self.mimeType = mimeType
        }
        open var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(PaperDocExportResultSerializer().serialize(self)))"
        }
    }
    open class PaperDocExportResultSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: PaperDocExportResult) -> JSON {
            let output = [ 
            "owner": Serialization._StringSerializer.serialize(value.owner),
            "title": Serialization._StringSerializer.serialize(value.title),
            "revision": Serialization._Int64Serializer.serialize(value.revision),
            "mime_type": Serialization._StringSerializer.serialize(value.mimeType),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> PaperDocExportResult {
            switch json {
                case .dictionary(let dict):
                    let owner = Serialization._StringSerializer.deserialize(dict["owner"] ?? .null)
                    let title = Serialization._StringSerializer.deserialize(dict["title"] ?? .null)
                    let revision = Serialization._Int64Serializer.deserialize(dict["revision"] ?? .null)
                    let mimeType = Serialization._StringSerializer.deserialize(dict["mime_type"] ?? .null)
                    return PaperDocExportResult(owner: owner, title: title, revision: revision, mimeType: mimeType)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The PaperDocPermissionLevel union
    public enum PaperDocPermissionLevel: CustomStringConvertible {
        /// User will be granted edit permissions.
        case edit
        /// User will be granted view and comment permissions.
        case viewAndComment
        /// An unspecified error.
        case other

        public var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(PaperDocPermissionLevelSerializer().serialize(self)))"
        }
    }
    open class PaperDocPermissionLevelSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: PaperDocPermissionLevel) -> JSON {
            switch value {
                case .edit:
                    var d = [String: JSON]()
                    d[".tag"] = .str("edit")
                    return .dictionary(d)
                case .viewAndComment:
                    var d = [String: JSON]()
                    d[".tag"] = .str("view_and_comment")
                    return .dictionary(d)
                case .other:
                    var d = [String: JSON]()
                    d[".tag"] = .str("other")
                    return .dictionary(d)
            }
        }
        open func deserialize(_ json: JSON) -> PaperDocPermissionLevel {
            switch json {
                case .dictionary(let d):
                    let tag = Serialization.getTag(d)
                    switch tag {
                        case "edit":
                            return PaperDocPermissionLevel.edit
                        case "view_and_comment":
                            return PaperDocPermissionLevel.viewAndComment
                        case "other":
                            return PaperDocPermissionLevel.other
                        default:
                            return PaperDocPermissionLevel.other
                    }
                default:
                    fatalError("Failed to deserialize")
            }
        }
    }

    /// The PaperDocSharingPolicy struct
    open class PaperDocSharingPolicy: Paper.RefPaperDoc {
        /// The default sharing policy to be set for the Paper doc.
        public let sharingPolicy: Paper.SharingPolicy
        public init(docId: String, sharingPolicy: Paper.SharingPolicy) {
            self.sharingPolicy = sharingPolicy
            super.init(docId: docId)
        }
        open override var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(PaperDocSharingPolicySerializer().serialize(self)))"
        }
    }
    open class PaperDocSharingPolicySerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: PaperDocSharingPolicy) -> JSON {
            let output = [ 
            "doc_id": Serialization._StringSerializer.serialize(value.docId),
            "sharing_policy": Paper.SharingPolicySerializer().serialize(value.sharingPolicy),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> PaperDocSharingPolicy {
            switch json {
                case .dictionary(let dict):
                    let docId = Serialization._StringSerializer.deserialize(dict["doc_id"] ?? .null)
                    let sharingPolicy = Paper.SharingPolicySerializer().deserialize(dict["sharing_policy"] ?? .null)
                    return PaperDocSharingPolicy(docId: docId, sharingPolicy: sharingPolicy)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The PaperDocUpdateArgs struct
    open class PaperDocUpdateArgs: Paper.RefPaperDoc {
        /// The policy used for the current update call.
        public let docUpdatePolicy: Paper.PaperDocUpdatePolicy
        /// The latest doc revision. This value must match the head revision or an error code will be returned. This is
        /// to prevent colliding writes.
        public let revision: Int64
        /// The format of provided data.
        public let importFormat: Paper.ImportFormat
        public init(docId: String, docUpdatePolicy: Paper.PaperDocUpdatePolicy, revision: Int64, importFormat: Paper.ImportFormat) {
            self.docUpdatePolicy = docUpdatePolicy
            comparableValidator()(revision)
            self.revision = revision
            self.importFormat = importFormat
            super.init(docId: docId)
        }
        open override var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(PaperDocUpdateArgsSerializer().serialize(self)))"
        }
    }
    open class PaperDocUpdateArgsSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: PaperDocUpdateArgs) -> JSON {
            let output = [ 
            "doc_id": Serialization._StringSerializer.serialize(value.docId),
            "doc_update_policy": Paper.PaperDocUpdatePolicySerializer().serialize(value.docUpdatePolicy),
            "revision": Serialization._Int64Serializer.serialize(value.revision),
            "import_format": Paper.ImportFormatSerializer().serialize(value.importFormat),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> PaperDocUpdateArgs {
            switch json {
                case .dictionary(let dict):
                    let docId = Serialization._StringSerializer.deserialize(dict["doc_id"] ?? .null)
                    let docUpdatePolicy = Paper.PaperDocUpdatePolicySerializer().deserialize(dict["doc_update_policy"] ?? .null)
                    let revision = Serialization._Int64Serializer.deserialize(dict["revision"] ?? .null)
                    let importFormat = Paper.ImportFormatSerializer().deserialize(dict["import_format"] ?? .null)
                    return PaperDocUpdateArgs(docId: docId, docUpdatePolicy: docUpdatePolicy, revision: revision, importFormat: importFormat)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The PaperDocUpdateError union
    public enum PaperDocUpdateError: CustomStringConvertible {
        /// Your account does not have permissions to perform this action.
        case insufficientPermissions
        /// An unspecified error.
        case other
        /// The required doc was not found.
        case docNotFound
        /// The provided content was malformed and cannot be imported to Paper.
        case contentMalformed
        /// The provided revision does not match the document head.
        case revisionMismatch
        /// The newly created Paper doc would be too large, split the content into multiple docs.
        case docLengthExceeded
        /// The imported document contains an image that is too large. The current limit is 1MB. Note: This only applies
        /// to HTML with data uri.
        case imageSizeExceeded
        /// This operation is not allowed on archived Paper docs.
        case docArchived
        /// This operation is not allowed on deleted Paper docs.
        case docDeleted

        public var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(PaperDocUpdateErrorSerializer().serialize(self)))"
        }
    }
    open class PaperDocUpdateErrorSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: PaperDocUpdateError) -> JSON {
            switch value {
                case .insufficientPermissions:
                    var d = [String: JSON]()
                    d[".tag"] = .str("insufficient_permissions")
                    return .dictionary(d)
                case .other:
                    var d = [String: JSON]()
                    d[".tag"] = .str("other")
                    return .dictionary(d)
                case .docNotFound:
                    var d = [String: JSON]()
                    d[".tag"] = .str("doc_not_found")
                    return .dictionary(d)
                case .contentMalformed:
                    var d = [String: JSON]()
                    d[".tag"] = .str("content_malformed")
                    return .dictionary(d)
                case .revisionMismatch:
                    var d = [String: JSON]()
                    d[".tag"] = .str("revision_mismatch")
                    return .dictionary(d)
                case .docLengthExceeded:
                    var d = [String: JSON]()
                    d[".tag"] = .str("doc_length_exceeded")
                    return .dictionary(d)
                case .imageSizeExceeded:
                    var d = [String: JSON]()
                    d[".tag"] = .str("image_size_exceeded")
                    return .dictionary(d)
                case .docArchived:
                    var d = [String: JSON]()
                    d[".tag"] = .str("doc_archived")
                    return .dictionary(d)
                case .docDeleted:
                    var d = [String: JSON]()
                    d[".tag"] = .str("doc_deleted")
                    return .dictionary(d)
            }
        }
        open func deserialize(_ json: JSON) -> PaperDocUpdateError {
            switch json {
                case .dictionary(let d):
                    let tag = Serialization.getTag(d)
                    switch tag {
                        case "insufficient_permissions":
                            return PaperDocUpdateError.insufficientPermissions
                        case "other":
                            return PaperDocUpdateError.other
                        case "doc_not_found":
                            return PaperDocUpdateError.docNotFound
                        case "content_malformed":
                            return PaperDocUpdateError.contentMalformed
                        case "revision_mismatch":
                            return PaperDocUpdateError.revisionMismatch
                        case "doc_length_exceeded":
                            return PaperDocUpdateError.docLengthExceeded
                        case "image_size_exceeded":
                            return PaperDocUpdateError.imageSizeExceeded
                        case "doc_archived":
                            return PaperDocUpdateError.docArchived
                        case "doc_deleted":
                            return PaperDocUpdateError.docDeleted
                        default:
                            fatalError("Unknown tag \(tag)")
                    }
                default:
                    fatalError("Failed to deserialize")
            }
        }
    }

    /// The PaperDocUpdatePolicy union
    public enum PaperDocUpdatePolicy: CustomStringConvertible {
        /// The content will be appended to the doc.
        case append
        /// The content will be prepended to the doc. Note: the doc title will not be affected.
        case prepend
        /// The document will be overwitten at the head with the provided content.
        case overwriteAll
        /// An unspecified error.
        case other

        public var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(PaperDocUpdatePolicySerializer().serialize(self)))"
        }
    }
    open class PaperDocUpdatePolicySerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: PaperDocUpdatePolicy) -> JSON {
            switch value {
                case .append:
                    var d = [String: JSON]()
                    d[".tag"] = .str("append")
                    return .dictionary(d)
                case .prepend:
                    var d = [String: JSON]()
                    d[".tag"] = .str("prepend")
                    return .dictionary(d)
                case .overwriteAll:
                    var d = [String: JSON]()
                    d[".tag"] = .str("overwrite_all")
                    return .dictionary(d)
                case .other:
                    var d = [String: JSON]()
                    d[".tag"] = .str("other")
                    return .dictionary(d)
            }
        }
        open func deserialize(_ json: JSON) -> PaperDocUpdatePolicy {
            switch json {
                case .dictionary(let d):
                    let tag = Serialization.getTag(d)
                    switch tag {
                        case "append":
                            return PaperDocUpdatePolicy.append
                        case "prepend":
                            return PaperDocUpdatePolicy.prepend
                        case "overwrite_all":
                            return PaperDocUpdatePolicy.overwriteAll
                        case "other":
                            return PaperDocUpdatePolicy.other
                        default:
                            return PaperDocUpdatePolicy.other
                    }
                default:
                    fatalError("Failed to deserialize")
            }
        }
    }

    /// The RemovePaperDocUser struct
    open class RemovePaperDocUser: Paper.RefPaperDoc {
        /// User which should be removed from the Paper doc. Specify only email address or Dropbox account ID.
        public let member: Sharing.MemberSelector
        public init(docId: String, member: Sharing.MemberSelector) {
            self.member = member
            super.init(docId: docId)
        }
        open override var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(RemovePaperDocUserSerializer().serialize(self)))"
        }
    }
    open class RemovePaperDocUserSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: RemovePaperDocUser) -> JSON {
            let output = [ 
            "doc_id": Serialization._StringSerializer.serialize(value.docId),
            "member": Sharing.MemberSelectorSerializer().serialize(value.member),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> RemovePaperDocUser {
            switch json {
                case .dictionary(let dict):
                    let docId = Serialization._StringSerializer.deserialize(dict["doc_id"] ?? .null)
                    let member = Sharing.MemberSelectorSerializer().deserialize(dict["member"] ?? .null)
                    return RemovePaperDocUser(docId: docId, member: member)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// Sharing policy of Paper doc.
    open class SharingPolicy: CustomStringConvertible {
        /// This value applies to the non-team members.
        public let publicSharingPolicy: Paper.SharingPublicPolicyType?
        /// This value applies to the team members only. The value is null for all personal accounts.
        public let teamSharingPolicy: Paper.SharingTeamPolicyType?
        public init(publicSharingPolicy: Paper.SharingPublicPolicyType? = nil, teamSharingPolicy: Paper.SharingTeamPolicyType? = nil) {
            self.publicSharingPolicy = publicSharingPolicy
            self.teamSharingPolicy = teamSharingPolicy
        }
        open var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(SharingPolicySerializer().serialize(self)))"
        }
    }
    open class SharingPolicySerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: SharingPolicy) -> JSON {
            let output = [ 
            "public_sharing_policy": NullableSerializer(Paper.SharingPublicPolicyTypeSerializer()).serialize(value.publicSharingPolicy),
            "team_sharing_policy": NullableSerializer(Paper.SharingTeamPolicyTypeSerializer()).serialize(value.teamSharingPolicy),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> SharingPolicy {
            switch json {
                case .dictionary(let dict):
                    let publicSharingPolicy = NullableSerializer(Paper.SharingPublicPolicyTypeSerializer()).deserialize(dict["public_sharing_policy"] ?? .null)
                    let teamSharingPolicy = NullableSerializer(Paper.SharingTeamPolicyTypeSerializer()).deserialize(dict["team_sharing_policy"] ?? .null)
                    return SharingPolicy(publicSharingPolicy: publicSharingPolicy, teamSharingPolicy: teamSharingPolicy)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The sharing policy type of the Paper doc.
    public enum SharingTeamPolicyType: CustomStringConvertible {
        /// Users who have a link to this doc can edit it.
        case peopleWithLinkCanEdit
        /// Users who have a link to this doc can view and comment on it.
        case peopleWithLinkCanViewAndComment
        /// Users must be explicitly invited to this doc.
        case inviteOnly

        public var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(SharingTeamPolicyTypeSerializer().serialize(self)))"
        }
    }
    open class SharingTeamPolicyTypeSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: SharingTeamPolicyType) -> JSON {
            switch value {
                case .peopleWithLinkCanEdit:
                    var d = [String: JSON]()
                    d[".tag"] = .str("people_with_link_can_edit")
                    return .dictionary(d)
                case .peopleWithLinkCanViewAndComment:
                    var d = [String: JSON]()
                    d[".tag"] = .str("people_with_link_can_view_and_comment")
                    return .dictionary(d)
                case .inviteOnly:
                    var d = [String: JSON]()
                    d[".tag"] = .str("invite_only")
                    return .dictionary(d)
            }
        }
        open func deserialize(_ json: JSON) -> SharingTeamPolicyType {
            switch json {
                case .dictionary(let d):
                    let tag = Serialization.getTag(d)
                    switch tag {
                        case "people_with_link_can_edit":
                            return SharingTeamPolicyType.peopleWithLinkCanEdit
                        case "people_with_link_can_view_and_comment":
                            return SharingTeamPolicyType.peopleWithLinkCanViewAndComment
                        case "invite_only":
                            return SharingTeamPolicyType.inviteOnly
                        default:
                            fatalError("Unknown tag \(tag)")
                    }
                default:
                    fatalError("Failed to deserialize")
            }
        }
    }

    /// The SharingPublicPolicyType union
    public enum SharingPublicPolicyType: CustomStringConvertible {
        /// Users who have a link to this doc can edit it.
        case peopleWithLinkCanEdit
        /// Users who have a link to this doc can view and comment on it.
        case peopleWithLinkCanViewAndComment
        /// Users must be explicitly invited to this doc.
        case inviteOnly
        /// Value used to indicate that doc sharing is enabled only within team.
        case disabled

        public var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(SharingPublicPolicyTypeSerializer().serialize(self)))"
        }
    }
    open class SharingPublicPolicyTypeSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: SharingPublicPolicyType) -> JSON {
            switch value {
                case .peopleWithLinkCanEdit:
                    var d = [String: JSON]()
                    d[".tag"] = .str("people_with_link_can_edit")
                    return .dictionary(d)
                case .peopleWithLinkCanViewAndComment:
                    var d = [String: JSON]()
                    d[".tag"] = .str("people_with_link_can_view_and_comment")
                    return .dictionary(d)
                case .inviteOnly:
                    var d = [String: JSON]()
                    d[".tag"] = .str("invite_only")
                    return .dictionary(d)
                case .disabled:
                    var d = [String: JSON]()
                    d[".tag"] = .str("disabled")
                    return .dictionary(d)
            }
        }
        open func deserialize(_ json: JSON) -> SharingPublicPolicyType {
            switch json {
                case .dictionary(let d):
                    let tag = Serialization.getTag(d)
                    switch tag {
                        case "people_with_link_can_edit":
                            return SharingPublicPolicyType.peopleWithLinkCanEdit
                        case "people_with_link_can_view_and_comment":
                            return SharingPublicPolicyType.peopleWithLinkCanViewAndComment
                        case "invite_only":
                            return SharingPublicPolicyType.inviteOnly
                        case "disabled":
                            return SharingPublicPolicyType.disabled
                        default:
                            fatalError("Unknown tag \(tag)")
                    }
                default:
                    fatalError("Failed to deserialize")
            }
        }
    }

    /// The UserInfoWithPermissionLevel struct
    open class UserInfoWithPermissionLevel: CustomStringConvertible {
        /// User shared on the Paper doc.
        public let user: Sharing.UserInfo
        /// Permission level for the user.
        public let permissionLevel: Paper.PaperDocPermissionLevel
        public init(user: Sharing.UserInfo, permissionLevel: Paper.PaperDocPermissionLevel) {
            self.user = user
            self.permissionLevel = permissionLevel
        }
        open var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(UserInfoWithPermissionLevelSerializer().serialize(self)))"
        }
    }
    open class UserInfoWithPermissionLevelSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: UserInfoWithPermissionLevel) -> JSON {
            let output = [ 
            "user": Sharing.UserInfoSerializer().serialize(value.user),
            "permission_level": Paper.PaperDocPermissionLevelSerializer().serialize(value.permissionLevel),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> UserInfoWithPermissionLevel {
            switch json {
                case .dictionary(let dict):
                    let user = Sharing.UserInfoSerializer().deserialize(dict["user"] ?? .null)
                    let permissionLevel = Paper.PaperDocPermissionLevelSerializer().deserialize(dict["permission_level"] ?? .null)
                    return UserInfoWithPermissionLevel(user: user, permissionLevel: permissionLevel)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The UserOnPaperDocFilter union
    public enum UserOnPaperDocFilter: CustomStringConvertible {
        /// all users who have visited the Paper doc.
        case visited
        /// All uses who are shared on the Paper doc. This includes all users who have visited the Paper doc as well as
        /// those who have not.
        case shared
        /// An unspecified error.
        case other

        public var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(UserOnPaperDocFilterSerializer().serialize(self)))"
        }
    }
    open class UserOnPaperDocFilterSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: UserOnPaperDocFilter) -> JSON {
            switch value {
                case .visited:
                    var d = [String: JSON]()
                    d[".tag"] = .str("visited")
                    return .dictionary(d)
                case .shared:
                    var d = [String: JSON]()
                    d[".tag"] = .str("shared")
                    return .dictionary(d)
                case .other:
                    var d = [String: JSON]()
                    d[".tag"] = .str("other")
                    return .dictionary(d)
            }
        }
        open func deserialize(_ json: JSON) -> UserOnPaperDocFilter {
            switch json {
                case .dictionary(let d):
                    let tag = Serialization.getTag(d)
                    switch tag {
                        case "visited":
                            return UserOnPaperDocFilter.visited
                        case "shared":
                            return UserOnPaperDocFilter.shared
                        case "other":
                            return UserOnPaperDocFilter.other
                        default:
                            return UserOnPaperDocFilter.other
                    }
                default:
                    fatalError("Failed to deserialize")
            }
        }
    }


    /// Stone Route Objects

    static let docsArchive = Route(
        name: "docs/archive",
        version: 1,
        namespace: "paper",
        deprecated: false,
        argSerializer: Paper.RefPaperDocSerializer(),
        responseSerializer: Serialization._VoidSerializer,
        errorSerializer: Paper.DocLookupErrorSerializer(),
        attrs: ["host": "api",
                "style": "rpc"]
    )
    static let docsCreate = Route(
        name: "docs/create",
        version: 1,
        namespace: "paper",
        deprecated: false,
        argSerializer: Paper.PaperDocCreateArgsSerializer(),
        responseSerializer: Paper.PaperDocCreateUpdateResultSerializer(),
        errorSerializer: Paper.PaperDocCreateErrorSerializer(),
        attrs: ["host": "api",
                "style": "upload"]
    )
    static let docsDownload = Route(
        name: "docs/download",
        version: 1,
        namespace: "paper",
        deprecated: false,
        argSerializer: Paper.PaperDocExportSerializer(),
        responseSerializer: Paper.PaperDocExportResultSerializer(),
        errorSerializer: Paper.DocLookupErrorSerializer(),
        attrs: ["host": "api",
                "style": "download"]
    )
    static let docsFolderUsersList = Route(
        name: "docs/folder_users/list",
        version: 1,
        namespace: "paper",
        deprecated: false,
        argSerializer: Paper.ListUsersOnFolderArgsSerializer(),
        responseSerializer: Paper.ListUsersOnFolderResponseSerializer(),
        errorSerializer: Paper.DocLookupErrorSerializer(),
        attrs: ["host": "api",
                "style": "rpc"]
    )
    static let docsFolderUsersListContinue = Route(
        name: "docs/folder_users/list/continue",
        version: 1,
        namespace: "paper",
        deprecated: false,
        argSerializer: Paper.ListUsersOnFolderContinueArgsSerializer(),
        responseSerializer: Paper.ListUsersOnFolderResponseSerializer(),
        errorSerializer: Paper.ListUsersCursorErrorSerializer(),
        attrs: ["host": "api",
                "style": "rpc"]
    )
    static let docsGetFolderInfo = Route(
        name: "docs/get_folder_info",
        version: 1,
        namespace: "paper",
        deprecated: false,
        argSerializer: Paper.RefPaperDocSerializer(),
        responseSerializer: Paper.FoldersContainingPaperDocSerializer(),
        errorSerializer: Paper.DocLookupErrorSerializer(),
        attrs: ["host": "api",
                "style": "rpc"]
    )
    static let docsList = Route(
        name: "docs/list",
        version: 1,
        namespace: "paper",
        deprecated: false,
        argSerializer: Paper.ListPaperDocsArgsSerializer(),
        responseSerializer: Paper.ListPaperDocsResponseSerializer(),
        errorSerializer: Serialization._VoidSerializer,
        attrs: ["host": "api",
                "style": "rpc"]
    )
    static let docsListContinue = Route(
        name: "docs/list/continue",
        version: 1,
        namespace: "paper",
        deprecated: false,
        argSerializer: Paper.ListPaperDocsContinueArgsSerializer(),
        responseSerializer: Paper.ListPaperDocsResponseSerializer(),
        errorSerializer: Paper.ListDocsCursorErrorSerializer(),
        attrs: ["host": "api",
                "style": "rpc"]
    )
    static let docsPermanentlyDelete = Route(
        name: "docs/permanently_delete",
        version: 1,
        namespace: "paper",
        deprecated: false,
        argSerializer: Paper.RefPaperDocSerializer(),
        responseSerializer: Serialization._VoidSerializer,
        errorSerializer: Paper.DocLookupErrorSerializer(),
        attrs: ["host": "api",
                "style": "rpc"]
    )
    static let docsSharingPolicyGet = Route(
        name: "docs/sharing_policy/get",
        version: 1,
        namespace: "paper",
        deprecated: false,
        argSerializer: Paper.RefPaperDocSerializer(),
        responseSerializer: Paper.SharingPolicySerializer(),
        errorSerializer: Paper.DocLookupErrorSerializer(),
        attrs: ["host": "api",
                "style": "rpc"]
    )
    static let docsSharingPolicySet = Route(
        name: "docs/sharing_policy/set",
        version: 1,
        namespace: "paper",
        deprecated: false,
        argSerializer: Paper.PaperDocSharingPolicySerializer(),
        responseSerializer: Serialization._VoidSerializer,
        errorSerializer: Paper.DocLookupErrorSerializer(),
        attrs: ["host": "api",
                "style": "rpc"]
    )
    static let docsUpdate = Route(
        name: "docs/update",
        version: 1,
        namespace: "paper",
        deprecated: false,
        argSerializer: Paper.PaperDocUpdateArgsSerializer(),
        responseSerializer: Paper.PaperDocCreateUpdateResultSerializer(),
        errorSerializer: Paper.PaperDocUpdateErrorSerializer(),
        attrs: ["host": "api",
                "style": "upload"]
    )
    static let docsUsersAdd = Route(
        name: "docs/users/add",
        version: 1,
        namespace: "paper",
        deprecated: false,
        argSerializer: Paper.AddPaperDocUserSerializer(),
        responseSerializer: ArraySerializer(Paper.AddPaperDocUserMemberResultSerializer()),
        errorSerializer: Paper.DocLookupErrorSerializer(),
        attrs: ["host": "api",
                "style": "rpc"]
    )
    static let docsUsersList = Route(
        name: "docs/users/list",
        version: 1,
        namespace: "paper",
        deprecated: false,
        argSerializer: Paper.ListUsersOnPaperDocArgsSerializer(),
        responseSerializer: Paper.ListUsersOnPaperDocResponseSerializer(),
        errorSerializer: Paper.DocLookupErrorSerializer(),
        attrs: ["host": "api",
                "style": "rpc"]
    )
    static let docsUsersListContinue = Route(
        name: "docs/users/list/continue",
        version: 1,
        namespace: "paper",
        deprecated: false,
        argSerializer: Paper.ListUsersOnPaperDocContinueArgsSerializer(),
        responseSerializer: Paper.ListUsersOnPaperDocResponseSerializer(),
        errorSerializer: Paper.ListUsersCursorErrorSerializer(),
        attrs: ["host": "api",
                "style": "rpc"]
    )
    static let docsUsersRemove = Route(
        name: "docs/users/remove",
        version: 1,
        namespace: "paper",
        deprecated: false,
        argSerializer: Paper.RemovePaperDocUserSerializer(),
        responseSerializer: Serialization._VoidSerializer,
        errorSerializer: Paper.DocLookupErrorSerializer(),
        attrs: ["host": "api",
                "style": "rpc"]
    )
}
