 }
 
 /**
-    Async "Force Remote" Accessor for retreiving latest `Bool` setting for the given key.
+    Async "Force Remote" Accessor for retreiving the latest setting of generic type `T` for given key.
  
-    Calls `refresh`, then if successful `completion` block with the latest remote value will be called.
-    If there is no value for given key on remote it works same as normal accessors (cache, local, fallback).
-    If `refresh` fails it will return `fallback` value in `completion` block.
+    This method will first call `refresh` method after which it will evaluate its success.
  
-    - parameter key: Key for the settings.
-    - parameter fallback: Default value for this setting if refresh not successful.
+    If `refresh` was successful, it will call normal accessor of generic type `T` for given key,
+    which will by its priority order resolve to the latest remote value as a parameter inside `completion` handler.
  
-    - returns: Latest `Bool` setting after successful refresh, otherwise provided `fallback` value.
-*/
-public func ConfigBoolForce(key: String, fallback: Bool, completion: ((forced: Bool) -> Void)) {
+    If `refresh` fails, it will return provided `fallback` value as a parameter inside `completion` block.
+
+    - parameter key: Key for the setting.
+    - parameter fallback: Fallback value of generic type `T` if refresh is not successful.
+*/
+public func ConfigGenericForce<T>(key: String, fallback: T, completion: ((forced: T) -> Void)) {
     MissionControl.refresh({ (innerBlock) in
         do {
             let _ = try innerBlock()
-            completion(forced: ConfigBool(key, fallback: fallback))
-        } catch {
-           completion(forced: fallback)
-        }
-    })
-}
-
-/**
-     Accessor for retreiving `Int` setting for the given key.
-     
-     It will get to proper setting by following this order:
-     1. Remote setting from memory (from last refresh).
-     2. Remote setting from disk cache (if not online).
-     3. Local setting from disk (if provided in `localConfig`).
-     4. Given fallback value (if provided).
-     5. Default fallback value (0)
-     
-     - parameter key: Key for the setting.
-     - parameter fallback: Default value for this setting if not available from configs. Defaults to 0.
-     
-     - returns: `Int` setting for the given key.
-*/
-public func ConfigInt(key: String, fallback: Int = 0) -> Int {
-    if let remoteValue = ACMissionControl.sharedInstance.remoteConfig?[key] as? Int {
-        return remoteValue
-    } else if let cachedValue = ACMissionControl.sharedInstance.cachedConfig?[key] as? Int {
-        return cachedValue
-    } else if let localValue = ACMissionControl.sharedInstance.localConfig?[key] as? Int {
-        return localValue
-    } else {
-        return fallback
-    }
-}
-
-/**
-    Async "Force Remote" Accessor for retreiving latest `Int` setting for the given key.
-
-    Calls `refresh`, then if successful `completion` block with the latest remote value will be called.
-    If there is no value for given key on remote it works same as normal accessors (cache, local, fallback).
-    If `refresh` fails it will return `fallback` value in `completion` block.
-
-    - parameter key: Key for the settings.
-    - parameter fallback: Default value for this setting if refresh not successful.
-
-    - returns: Latest `Int` setting after successful refresh, otherwise provided `fallback` value.
-*/
-public func ConfigIntForce(key: String, fallback: Int, completion: ((forced: Int) -> Void)) {
-    MissionControl.refresh({ (innerBlock) in
-        do {
-            let _ = try innerBlock()
-            completion(forced: ConfigInt(key, fallback: fallback))
+            completion(forced: ConfigGeneric(key, fallback: fallback))
         } catch {
             completion(forced: fallback)
         }

}

/**
     Accessor for retreiving `Double` setting for the given key.
     
     It will get to proper setting by following this order:
     1. Remote setting from memory (from last refresh).
     2. Remote setting from disk cache (if not online).
     3. Local setting from disk (if provided in `localConfig`).
     4. Given fallback value (if provided).
     5. Default fallback value (0.0)
     
     - parameter key: Key for the setting.
     - parameter fallback: Default value for this setting if not available from configs. Defaults to 0.0.
     
     - returns: `Double` setting for the given key.
*/
public func ConfigDouble(key: String, fallback: Double = 0.0) -> Double {
    if let remoteValue = ACMissionControl.sharedInstance.remoteConfig?[key] as? Double {
        return remoteValue
    } else if let cachedValue = ACMissionControl.sharedInstance.cachedConfig?[key] as? Double {
        return cachedValue
    } else if let localValue = ACMissionControl.sharedInstance.localConfig?[key] as? Double {
        return localValue
    } else {
        return fallback
    }
}

/**
    Async "Force Remote" Accessor for retreiving latest `Double` setting for the given key.

    Calls `refresh`, then if successful `completion` block with the latest remote value will be called.
    If there is no value for given key on remote it works same as normal accessors (cache, local, fallback).
    If `refresh` fails it will return `fallback` value in `completion` block.

    - parameter key: Key for the settings.
    - parameter fallback: Default value for this setting if refresh not successful.

    - returns: Latest `Double` setting after successful refresh, otherwise provided `fallback` value.
*/
public func ConfigDoubleForce(key: String, fallback: Double, completion: ((forced: Double) -> Void)) {
    MissionControl.refresh({ (innerBlock) in
        do {
            let _ = try innerBlock()
            completion(forced: ConfigDouble(key, fallback: fallback))
        } catch {
            completion(forced: fallback)
        }
    })
}

/**
    Accessor for retreiving `String` setting for the given key.

    It will get to proper setting by following this order:
    1. Remote setting from memory (from last refresh).
    2. Remote setting from disk cache (if not online).
    3. Local setting from disk (if provided in `localConfig`).
    4. Given fallback value (if provided).
    5. Default fallback value ("")

    - parameter key: Key for the setting.
    - parameter fallback: Default value for this setting if not available from configs. Defaults to empty string.

    - returns: `String` setting for the given key.
*/
public func ConfigString(key: String, fallback: String = String()) -> String {
    if let remoteValue = ACMissionControl.sharedInstance.remoteConfig?[key] as? String {
        return remoteValue
    } else if let cachedValue = ACMissionControl.sharedInstance.cachedConfig?[key] as? String {
        return cachedValue
    } else if let localValue = ACMissionControl.sharedInstance.localConfig?[key] as? String {
        return localValue
    } else {
        return fallback
    }
}

/**
    Async "Force Remote" Accessor for retreiving latest `String` setting for the given key.

    Calls `refresh`, then if successful `completion` block with the latest remote value will be called.
    If there is no value for given key on remote it works same as normal accessors (cache, local, fallback).
    If `refresh` fails it will return `fallback` value in `completion` block.

    - parameter key: Key for the settings.
    - parameter fallback: Default value for this setting if refresh not successful.

    - returns: Latest `String` setting after successful refresh, otherwise provided `fallback` value.
*/
public func ConfigStringForce(key: String, fallback: String, completion: ((forced: String) -> Void)) {
    MissionControl.refresh({ (innerBlock) in
        do {
            let _ = try innerBlock()
            completion(forced: ConfigString(key, fallback: fallback))
        } catch {
            completion(forced: fallback)
        }
    })
}

// MARK: - ACMissionControl

// MARK: - Accessors

/**
    Accessor for retreiving setting of generic type `T` for given key.

    This method will resolve to proper setting by following this priority order:
    1. Remote setting from memory (received in the last refresh).
    2. Remote setting from disk cache (if never refreshed in current app session (ex. offline)).
    3. Local setting from disk (defaults provided in `localConfig` on MissionControl `launch`).
    4. Provided fallback value (if provided)

    - parameter key: Key for the setting.
    - parameter fallback: Fallback value if setting is not available in any config.

    - returns: Resolved setting of generic type `T` for given key.
*/
public func ConfigGeneric<T>(key: String, fallback: T) -> T {
    if let remoteValue = ACMissionControl.sharedInstance.remoteConfig?[key] as? T {
        return remoteValue
    } else if let cachedValue = ACMissionControl.sharedInstance.cachedConfig?[key] as? T {
        return cachedValue
    } else if let localValue = ACMissionControl.sharedInstance.localConfig?[key] as? T {
        return localValue
    } else {
        return fallback
