     public let isa: TypeReference?
     /// Indicatow whether this type is an alias that doesn't need casting
     public let isAlias: Bool
-    /// Dictionary of possible type conversion (cast) operations to target types
-    public var conversions: [GIRType : TypeConversion] = [:]
+    /// Dictionary of possible type conversion (cast) operations to target types.
+    /// - Note: The index into the array is the level of constness and indirection*2,
+    /// e.g., `0` is direct, non-const, `1` is direct and `const`, `2` is a single-level,
+    /// mutable pointer, `3`, is a single-level immutable pointer, `4` is a mutable pointer
+    /// to a pointer, `5` is an immutable pointer to a pointer, etc.
+    public var conversions: [GIRType : [TypeConversion]] = [:]
 
     /// Designated initialiser for a GIR type
     /// - Parameters:


    static let stringTypes: Set<GIRType> = [stringType, constStringType, gstringType, constGStringType, gustringType, constGUStringType]

    /// Common aliases used
    static var aliases: Set<GIRType> = {[
        GIRType(aliasOf: guintType, ctype: "unsigned int"),

        self.init(aliasOf: TypeReference(type: aliasOf), name: name, swiftName: swiftName, ctype: ctype)
    }

    /// Return an explicitly known cast to convert the given expression to the target type
    /// - Parameters:
    ///   - expression: The expression to cast
    ///   - target: The target type to cast to
    ///   - pointerLevel: The number of indirection levels (pointers)
    ///   - const: An indicator whether the cast is to a `const` value
    /// - Returns: The cast expression string, or `nil` if there is no way to cast to `target`
    @inlinable
    public func knownCast(expression: String, to target: GIRType, pointerLevel: Int = 0, const: Bool = false) -> String? {
        guard let conversion = conversions[target] else { return nil }
        let i = 2*pointerLevel + (const ? 1 : 0)
        guard i < conversion.count else { return nil }
        return conversion[i].castToTarget(from: expression)
    }

    /// Return  an explicitly known cast to convert the given expression to the target type
    /// - Parameters:
    ///   - expression: The expression to cast
    ///   - source: The source type to cast from
    ///   - pointerLevel: The number of indirection levels (pointers)
    ///   - const: An indicator whether the cast is to a `const` value
    /// - Returns: The cast expression string, or `nil` if there is no way to cast from `source`
    @inlinable
    public func knownCast(expression e: String, from source: GIRType, pointerLevel: Int = 0, const: Bool = false) -> String? {
        guard let conversion = conversions[source] else { return nil }
        let i = 2*pointerLevel + (const ? 1 : 0)
        guard i < conversion.count else { return nil }
        return conversion[i].castFromTarget(expression: e)
    }

    /// Return the default cast to convert the given expression to the target type
    /// - Parameters:
    ///   - expression: The expression to cast
    ///   - target: The target type to cast to
    ///   - pointerLevel: The number of indirection levels (pointers)
    ///   - const: An indicator whether the cast is to a `const` value
    /// - Returns: The cast expression string, or `nil` if there is no way to cast to `target`
    @inlinable
    public func cast(expression: String, to target: GIRType, pointerLevel: Int = 0, const: Bool = false) -> String? {
        if let castExpr = knownCast(expression: expression, to: target, pointerLevel: pointerLevel, const: const) {
            return castExpr
        }
        let prefix: String
        if pointerLevel == 0 {
            prefix = target.swiftName
        } else {
            let ptr = const ? "UnsafePointer" : "UnsafeMutablePointer"
            prefix = ptr + "<" + target.swiftName + ">"
        }
        return prefix + "(" + expression + ")"
    }

    /// Return the default cast to convert the given expression to the target type
    /// - Parameters:
    ///   - expression: The expression to cast
    ///   - source: The source type to cast from
    ///   - pointerLevel: The number of indirection levels (pointers)
    ///   - const: An indicator whether the cast is to a `const` value
    /// - Returns: The cast expression string, or `nil` if there is no way to cast from `source`
    @inlinable
    public func cast(expression e: String, from source: GIRType, pointerLevel: Int = 0, const: Bool = false) -> String? {
        if let castExpr = knownCast(expression: e, from: source, pointerLevel: pointerLevel, const: const) {
            return castExpr
        }
        let prefix: String
        if pointerLevel == 0 {
            prefix = swiftName
        } else {
            let ptr = const ? "UnsafePointer" : "UnsafeMutablePointer"
            prefix = ptr + "<" + swiftName + ">"
        }
        return prefix + "(" + e + ")"
    }

    /// Equality check for a type.
