@Override
 public void destroy() {
   if ((!destroyed) && (circuitKey != null)) {
     CMLib.tech().unregisterElectronics(this, circuitKey);
     circuitKey = null;
   }
   super.destroy();
 }
 @Override
 public void setOwner(ItemPossessor newOwner) {
   final ItemPossessor prevOwner = super.owner;
   super.setOwner(newOwner);
   if (prevOwner != newOwner) {
     if (newOwner instanceof Room) circuitKey = CMLib.tech().registerElectrics(this, circuitKey);
     else {
       CMLib.tech().unregisterElectronics(this, circuitKey);
       circuitKey = null;
     }
   }
 }
 @Override
 public void executeMsg(Environmental host, CMMsg msg) {
   if (msg.amITarget(this)) {
     switch (msg.targetMinor()) {
       case CMMsg.TYP_ACTIVATE:
         if ((msg.source().location() != null)
             && (!CMath.bset(msg.targetMajor(), CMMsg.MASK_CNTRLMSG)))
           msg.source()
               .location()
               .show(msg.source(), this, CMMsg.MSG_OK_VISUAL, L("<S-NAME> activate(s) <T-NAME>."));
         this.activate(true);
         break;
       case CMMsg.TYP_DEACTIVATE:
         if ((msg.source().location() != null)
             && (!CMath.bset(msg.targetMajor(), CMMsg.MASK_CNTRLMSG)))
           msg.source()
               .location()
               .show(
                   msg.source(), this, CMMsg.MSG_OK_VISUAL, L("<S-NAME> deactivate(s) <T-NAME>."));
         this.activate(false);
         break;
       case CMMsg.TYP_LOOK:
         super.executeMsg(host, msg);
         if (CMLib.flags().canBeSeenBy(this, msg.source()))
           msg.source()
               .tell(
                   L(
                       "@x1 is currently @x2",
                       name(),
                       (activated() ? "connected.\n\r" : "deactivated/disconnected.\n\r")));
         return;
       case CMMsg.TYP_REPAIR:
         if (CMLib.dice().rollPercentage() < msg.value()) {
           setUsesRemaining(usesRemaining() < 100 ? 100 : usesRemaining());
           msg.source().tell(L("@x1 is now repaired.\n\r", name()));
         } else {
           final int repairRequired = 100 - usesRemaining();
           if (repairRequired > 0) {
             int repairApplied =
                 (int) Math.round(CMath.mul(repairRequired, CMath.div(msg.value(), 100)));
             if (repairApplied < 0) repairApplied = 1;
             setUsesRemaining(usesRemaining() + repairApplied);
             msg.source().tell(L("@x1 is now @x2% repaired.\n\r", name(), "" + usesRemaining()));
           }
         }
         break;
       case CMMsg.TYP_ENHANCE:
         if ((CMLib.dice().rollPercentage() < msg.value())
             && (CMLib.dice().rollPercentage() < 50)) {
           float addAmt = 0.01f;
           if (getInstalledFactor() < 1.0) {
             addAmt = (float) (CMath.div(100.0, msg.value()) * 0.1);
             if (addAmt < 0.1f) addAmt = 0.1f;
           }
           setInstalledFactor(this.getInstalledFactor() + addAmt);
           msg.source().tell(msg.source(), this, null, L("<T-NAME> is now enhanced.\n\r"));
         } else {
           msg.source()
               .tell(
                   msg.source(),
                   this,
                   null,
                   L("Your attempt to enhance <T-NAME> has failed.\n\r"));
         }
         break;
     }
   }
   super.executeMsg(host, msg);
 }