  * Note: this is an abstract class, when building new keys using
  * globalIDWithEntityName(), you will get private subclasses.
  */
-public class KeyGlobalID : GlobalID {
+public class KeyGlobalID : GlobalID, CustomStringConvertible {
   
   public let entityName : String
   
+  @inlinable
   public init(entityName: String) {
     self.entityName = entityName
   }
   
+  @inlinable
   open var keyCount : Int { return 0 }
   
+  @inlinable
   open subscript(i: Int) -> Any? { return nil }
 
   static func make(entityName: String, values: [ Any? ]) -> KeyGlobalID {
-    if values.count == 1, let i = values[0] as? Int {
-      return SingleIntKeyGlobalID(entityName: entityName, value: i)
+    if values.count == 1, let v = values.first {
+      switch v {
+        case let i as Int:
+          return SingleIntKeyGlobalID(entityName: entityName, value: i)
+        case let i as Int64:
+          return SingleIntKeyGlobalID(entityName: entityName, value: Int(i))
+        case let i as Int32:
+          return SingleIntKeyGlobalID(entityName: entityName, value: Int(i))
+        case let i as UInt32: // assumes 64-bit
+          return SingleIntKeyGlobalID(entityName: entityName, value: Int(i))
+        default:
+          break
+      }
     }
     return ComplexKeyGlobalID(entityName: entityName, values: values)
+  }
+
+  public var description: String {
+    var ms = "<GID: \(entityName)"
+    for i in 0..<keyCount {
+      if let v = self[i] { ms += " \(v)"  }
+      else               { ms += " <nil>" }
+    }
+    ms += ">"
+    return ms
   }
 }
 

    super.init(entityName: entityName)
  }
  
  override public var keyCount : Int { return values.count }
  
  override public subscript(i: Int) -> Any? {
    guard i < values.count else { return nil }
    return values[i]
  }
  
  override public func hash(into hasher: inout Hasher) {
    entityName.hash(into: &hasher)
    String(describing: values[0]).hash(into: &hasher)
  }
  
  override public func isEqual(to object: Any?) -> Bool {
    // TODO: compare against SingleIntKeyGlobalID
    guard let gid = object as? ComplexKeyGlobalID else { return false }

  
  public let value : Int
  
  @inlinable
  public init(entityName: String, value: Int) {
    self.value = value
    super.init(entityName: entityName)
  }

  @inlinable
  override public var keyCount : Int { return 1 }

  @inlinable
  override public subscript(i: Int) -> Any? {
    guard i == 0 else { return nil }
    return value
  }
  
  @inlinable
  override public func hash(into hasher: inout Hasher) {
    entityName.hash(into: &hasher)
    value     .hash(into: &hasher)
  }
  
  @inlinable
  override public func isEqual(to object: Any?) -> Bool {
    guard let gid = object as? SingleIntKeyGlobalID else {
      if let complex = object as? ComplexKeyGlobalID {
        return complex.isEqual(to: self)
      }
      return false
    }
    return value == gid.value && entityName == gid.entityName
  }

  override public var description: String {
    return "<GIDi: \(entityName) \(value)>"
  }
}

