     ]
   }
 
-  private func map(_ relationship: CoreData.Relationship) -> [String: Any] {
+  private func map(_ relationship: CoreData.Relationship, in model: CoreData.Model) -> [String: Any] {
     return [
       "name": relationship.name,
       "isIndexed": relationship.isIndexed,

  private func map(_ model: CoreData.Model) -> [String: Any] {
    return [
      "configurations": model.configurations,
      "entities": model.entities.mapValues(map),
      "fetchRequests": model.fetchRequests.map(map),
      "fetchRequestsByEntityName": model.fetchRequestsByEntityName.mapValues { $0.map(map) }
    ]
  }

  private func map(_ entity: CoreData.Entity) -> [String: Any] {
    return [
      "name": entity.name,
      "className": entity.className,
      "isAbstract": entity.isAbstract,
      "userInfo": entity.userInfo,
      "superentity": entity.superentity ?? "",
      "attributes": entity.attributes.map(map),
      "relationships": entity.relationships.map(map),
      "fetchedProperties": entity.fetchedProperties.map(map)
    ]
  }

  private func map(_ attribute: CoreData.Attribute) -> [String: Any] {
    return [
      "name": attribute.name,
      "isIndexed": attribute.isIndexed,

      return "Dictionary"
    }
  }

  private func substitutionVariables(
    in predicateString: String,
    baseEntity: CoreData.Entity,
    model: CoreData.Model
  ) -> [String: String] {
    if predicateString.isEmpty { return [:] }
    let predicate = NSPredicate(format: predicateString, argumentArray: nil)
    return substitutionVariables(in: predicate, baseEntity: baseEntity, model: model)
  }

  private func substitutionVariables(
    in predicate: NSPredicate,
    baseEntity: CoreData.Entity,
    model: CoreData.Model
  ) -> [String: String] {
    if let compoundPredicate = predicate as? NSCompoundPredicate {
      return compoundPredicate.subpredicates.reduce(into: [:]) { variables, subpredicate in
        guard let subpredicate = subpredicate as? NSPredicate else { return }
        let subpredicateVariables = substitutionVariables(in: subpredicate, baseEntity: baseEntity, model: model)
        variables.merge(subpredicateVariables) { existing, _ in existing }
      }
    } else if let comparisonPredicate = predicate as? NSComparisonPredicate {
      let lhs = comparisonPredicate.leftExpression
      let rhs = comparisonPredicate.rightExpression

      guard rhs.expressionType == .variable else { return [:] }

      let typeName = resolveType(forKeyPath: lhs.keyPath, baseEntity: baseEntity, in: model)
      return [rhs.variable: typeName]
    } else {
      return [:]
    }
  }

  private func resolveType(
    forKeyPath keyPath: String,
    baseEntity: CoreData.Entity,
    in model: CoreData.Model
  ) -> String {
    let components = keyPath.split(separator: ".")

    var entity = baseEntity
    for component in components {
      if let attribute = entity.attributes.first(where: { $0.name == component }) {
        return attribute.typeName
      } else if let relationship = entity.relationships.first(where: { $0.name == component }) {
        guard let destinationEntity = model.entities[relationship.destinationEntity] else {
          return ""
        }
        entity = destinationEntity
      }
    }

    return entity.className
  }
}
