pragma.enable("easy-return")
pragma.disable("explicit-result-guard")

def makeBrand implements DeepFrozen {
 to run(label :String) :any {

   # This holds nullOk[Tuple[any]], but stating so now creates a
   # circular dependency makeBrand->nullOk->DeepFrozen, and is not
   # necessary since all the assignments maintain that condition.
   var unsealHolder := null

   def brand {
     to __printOn(out :TextWriter) :void {
       out.print(label)
     }
   }

   def sealer {
     to __printOn(out :TextWriter) :void {
       out.print("<", brand, " sealer>")
     }

     # XXX optSealedDispatch uncall

     /** Return the Brand of this sealer/unsealer set. */
     to getBrand() :any { return brand }

     to seal(content) {
       def sealedBox {
         to __printOn(out :TextWriter) :void {
           out.print("<sealed by ", brand, ">")
         }

         # XXX optSealedDispatch uncall

         /** Return the Brand of the Unsealer which can unseal this
          *  box. */
         to getBrand() :any { return brand }

         /** An implementation detail. */
         to _offerContent() :void {
           unsealHolder := [content]
         }
       }
       return sealedBox
     }
   }

   def unsealer {
     to __printOn(out :TextWriter) :void {
       out.print("<", brand, " unsealer>")
     }

     # XXX optSealedDispatch uncall

     /** Return the Brand of this sealer/unsealer set. */
     to getBrand() :any { return brand }

     /** .unseal(specimen, null) */
     to unseal(specimen) :any {
       return unsealer.unseal(specimen, null)
     }

     # The implementation structure is partially described in the
     # documentation here since it affects how the unsealer behaves
     # when given an object which pretends to be our sealed box.
     /** Unseal a SealedBox: return its contents.
       * 
       * Call specimen._offerContent(), then return the contents of the 
       * sealed box (of our brand), if any, whose _offerContent/0 
       * method is invoked last during the call.
       *
       * Note that an object which successfully unseals will not
       * necessarily give the same contents on a second unsealing. */
     to unseal(specimen, optEjector) :any {
       try {
         unsealHolder := null

         if (specimen.__respondsTo("_offerContent", 0) \
             && (specimen._offerContent(); 
                 unsealHolder =~ [content])) {
           return content
         } else {
           # XXX exception type
           # XXX distinguish not-a-box from not-our-box from
           # pretending-to-be-our-box?
           throw.eject(optEjector,
             `$specimen is not a $brand sealed box`)
         }
       } finally {
         unsealHolder := null
       }
     }
   }

   def brandKit {
     to __printOn(out :TextWriter) :void {
       out.print("<", brand, " brand kit>")
     }

     # XXX optUncall

     # XXX add list-imitating get/1
     # XXX no tests for getSealer, getUnsealer

     to getSealer() :any { return sealer }
     to getUnsealer() :any { return unsealer }

     /** Return the Brand of this sealer/unsealer set. */
     to getBrand() :any { return brand }

     /** This brand kit will coerce to a tuple, so that it may be
      *  matched against a list pattern like
      *  epatt`[sealer, unsealer]`. */
     to __conformTo(guard) :any { switch (guard) {
       match ==<type:org.erights.e.elib.tables.ConstList> {
         return [sealer, unsealer]
       }
       match _ { return brandKit }
     }}
   }

   return brandKit
 }
}