         return merged
     }
 
+    static func resolveTargetTemplates(jsonDictionary: JSONDictionary) -> JSONDictionary {
+        return resolveTemplates(jsonDictionary: jsonDictionary,
+                                templateStructure: TemplateStructure(baseKey: "targets",
+                                                                     templatesKey: "targetTemplates",
+                                                                     nameToReplace: "target_name"))
+    }
+
     static func resolveSchemeTemplates(jsonDictionary: JSONDictionary) -> JSONDictionary {
-        guard var schemesDictionary: [String: JSONDictionary] = jsonDictionary["schemes"] as? [String: JSONDictionary] else {
+        return resolveTemplates(jsonDictionary: jsonDictionary,
+                                templateStructure: TemplateStructure(baseKey: "schemes",
+                                                                     templatesKey: "schemeTemplates",
+                                                                     nameToReplace: "scheme_name"))
+    }
+
+    private static func resolveTemplates(jsonDictionary: JSONDictionary, templateStructure: TemplateStructure) -> JSONDictionary {
+        guard var baseDictionary: [String: JSONDictionary] = jsonDictionary[templateStructure.baseKey] as? [String: JSONDictionary] else {
             return jsonDictionary
         }
 
-        let schemeTemplatesDictionary: [String: JSONDictionary] = jsonDictionary["schemeTemplates"] as? [String: JSONDictionary] ?? [:]
+        let templatesDictionary: [String: JSONDictionary] = jsonDictionary[templateStructure.templatesKey] as? [String: JSONDictionary] ?? [:]
 
         // Recursively collects all nested template names of a given dictionary.
         func collectTemplates(of jsonDictionary: JSONDictionary,

            }
        }

        for (schemeName, var scheme) in schemesDictionary {
            var templates: [String] = []
            var index: Int = 0
            collectTemplates(of: scheme, into: &templates, insertAt: &index)
            if !templates.isEmpty {
                var mergedDictionary: JSONDictionary = [:]
                for template in templates {
                    if let templateDictionary = schemeTemplatesDictionary[template] {
                        mergedDictionary = templateDictionary.merged(onto: mergedDictionary)
                    }
                }
                scheme = scheme.merged(onto: mergedDictionary)
                scheme = scheme.replaceString("${scheme_name}", with: schemeName)
                if let templateAttributes = scheme["templateAttributes"] as? [String: String] {
                    for (templateAttribute, value) in templateAttributes {
                        scheme = scheme.replaceString("${\(templateAttribute)}", with: value)
                    }
                }
            }
            schemesDictionary[schemeName] = scheme
        }

        var jsonDictionary = jsonDictionary
        jsonDictionary["schemes"] = schemesDictionary
        return jsonDictionary
    }
}

    }
}

struct TemplateStructure {
    let baseKey: String
    let templatesKey: String
    let nameToReplace: String
}

extension Target: CustomStringConvertible {

    public var description: String {
