 import Vapor
 
 public protocol AccountRoutes {
-    func create(type: ConnectedAccountType, email: String?, country: String?, metadata: [String: String]?) throws -> Future<StripeConnectAccount>
+    func create(type: ConnectedAccountType, email: String?, country: String?, accountToken: String?, businessLogo: String?, businessName: String?, businessPrimaryColor: String?, businessUrl: String?, debitNegativeBalances: Bool?, declineChargeOn: [String: Bool]?, defaultCurrency: StripeCurrency?, externalAccount: Any?, legalEntity: StripeConnectAccountLegalEntity?, metadata: [String: String]?, payoutSchedule: [String: String]?, payoutStatementDescriptor: String?, productDescription: String?, statementDescriptor: String?, supportEmail: String?, supportPhone: String?, supportUrl: String?, tosAcceptance: StripeTOSAcceptance?) throws -> Future<StripeConnectAccount>
     func retrieve(account: String) throws -> Future<StripeConnectAccount>
     func update(account: String, businessName: String?, businessPrimaryColor: String?, businessUrl: String?, debitNegativeBalances: Bool?, declineChargeOn: [String: Bool]?, defaultCurrency: StripeCurrency?, email: String?, externalAccount: Any?, legalEntity: StripeConnectAccountLegalEntity?, metadata: [String: String]?, payoutSchedule: [String: String]?, payoutStatementDescriptor: String?, productDescription: String?, statementDescriptor: String?, supportEmail: String?, supportPhone: String?, supportUrl: String?, tosAcceptance: StripeTOSAcceptance?) throws -> Future<StripeConnectAccount>
     func delete(account: String) throws -> Future<StripeDeletedObject>

    public func create(type: ConnectedAccountType,
                       email: String?,
                       country: String?,
                       metadata: [String: String]?) throws -> Future<StripeConnectAccount> {
        var body: [String: String] = [:]
        body["type"] = type.rawValue
        
        if let email = email {
            body["email"] = email
        }
        
        if let country = country {
            body["country"] = country
        }
        
        if let metadata = metadata {
            metadata.forEach { body["metadata[\($0)]"] = $1 }
        }
        
        return try request.send(method: .POST, path: StripeAPIEndpoint.account.endpoint, body: body.queryParameters)

}

extension AccountRoutes {
    public func create(type: ConnectedAccountType,
                       email: String? = nil,
                       country: String? = nil,
                       accountToken: String? = nil,
                       businessLogo: String? = nil,
                       businessName: String? = nil,
                       businessPrimaryColor: String? = nil,
                       businessUrl: String? = nil,
                       debitNegativeBalances: Bool? = nil,
                       declineChargeOn: [String: Bool]? = nil,
                       defaultCurrency: StripeCurrency? = nil,
                       externalAccount: Any? = nil,
                       legalEntity: StripeConnectAccountLegalEntity? = nil,
                       metadata: [String: String]? = nil,
                       payoutSchedule: [String: String]? = nil,
                       payoutStatementDescriptor: String? = nil,
                       productDescription: String? = nil,
                       statementDescriptor: String? = nil,
                       supportEmail: String? = nil,
                       supportPhone: String? = nil,
                       supportUrl: String? = nil,
                       tosAcceptance: StripeTOSAcceptance? = nil) throws -> Future<StripeConnectAccount> {
        return try create(type: type,
                          email: email,
                          country: country,
                          accountToken: accountToken,
                          businessLogo: businessLogo,
                          businessName: businessName,
                          businessPrimaryColor: businessPrimaryColor,
                          businessUrl: businessUrl,
                          debitNegativeBalances: debitNegativeBalances,
                          declineChargeOn: declineChargeOn,
                          defaultCurrency: defaultCurrency,
                          externalAccount: externalAccount,
                          legalEntity: legalEntity,
                          metadata: metadata,
                          payoutSchedule: payoutSchedule,
                          payoutStatementDescriptor: payoutStatementDescriptor,
                          productDescription: productDescription,
                          statementDescriptor: statementDescriptor,
                          supportEmail: supportEmail,
                          supportPhone: supportPhone,
                          supportUrl: supportUrl,
                          tosAcceptance: tosAcceptance)
    }
    
    public func retrieve(account: String) throws -> Future<StripeConnectAccount> {
