/**
  * Returns the avatar renderer for the primary view cell, or null if none exists.
  *
  * @return An instance of this class that is the avatar cell renderer
  */
 public static AvatarImiJME getPrimaryAvatarRenderer() {
   // Fetch the primary view cell, make sure it is an avatar and then get
   // its cell renderer.
   ViewCell cell = ClientContextJME.getViewManager().getPrimaryViewCell();
   if (cell instanceof AvatarCell) {
     AvatarCell avatarCell = (AvatarCell) cell;
     return (AvatarImiJME) avatarCell.getCellRenderer(ClientContext.getRendererType());
   }
   return null;
 }
  public void initialize() throws AudioCacheHandlerException {
    audioCacheDir =
        new File(
            ClientContext.getUserDirectory().getAbsolutePath()
                + File.separator
                + "cache"
                + File.separator
                + "audio");

    logger.warning("Audio cache dir " + audioCacheDir.getAbsolutePath());

    if (audioCacheDir.isDirectory() == false) {
      if (audioCacheDir.exists()) {
        throw new AudioCacheHandlerException(
            "Invalid audio cache directory " + audioCacheDir.getAbsolutePath());
      } else {
        if (audioCacheDir.mkdir() == false) {
          throw new AudioCacheHandlerException("Unable to create audio cache directory");
        }
      }
    }
  }
  /** {@inheritDoc} */
  @Override
  public void setStatus(CellStatus status, boolean increasing) {
    super.setStatus(status, increasing);
    WlAvatarCharacter pendingAvatar = null;

    logger.info("AVATAR RENDERER STATUS " + status + " DIR " + increasing);

    // If we are increasing to the ACTIVE state, then turn everything on.
    // Add the listeners to the avatar Cell and set the avatar character
    if (status == CellStatus.ACTIVE && increasing == true) {
      BoundsDebugger.getInstance().add(this);
      if (cellMoveListener != null) {
        // mc should not be null, but sometimes it seems to be
        MovableComponent mc = cell.getComponent(MovableComponent.class);
        if (mc == null) {
          logger.severe("NULL MovableComponent in avatar " + ((AvatarCell) cell).getName());
        } else {
          mc.removeServerCellMoveListener(cellMoveListener);
        }
        cellMoveListener = null;
      }

      // If we have not creating the avatar yet, then look for the config
      // component on the cell. Fetch the avatar configuration.
      if (avatarCharacter == null) {
        AvatarConfigComponent configComp = cell.getComponent(AvatarConfigComponent.class);
        AvatarConfigInfo avatarConfigInfo = null;
        if (configComp != null) {
          avatarConfigInfo = configComp.getAvatarConfigInfo();
        }
        logger.info("LOADING AVATAR FOR " + avatarConfigInfo);
        pendingAvatar = loadAvatar(avatarConfigInfo);
      } else {
        // Otherwise remove the existing avatar from the world
        ClientContextJME.getWorldManager().removeEntity(avatarCharacter);
        pendingAvatar = null;
      }

      // Go ahead and change the avatar
      logger.info("CHANGING AVATAR IN SET STATUS");
      changeAvatar(pendingAvatar);

      if (cellMoveListener == null) {
        cellMoveListener =
            new CellMoveListener() {
              public void cellMoved(CellTransform transform, CellMoveSource source) {
                if (source == CellMoveSource.REMOTE) {
                  //                            System.err.println("REMOTE MOVE
                  // "+transform.getTranslation(null));
                  if (avatarCharacter != null) {
                    if (avatarCharacter.getModelInst() == null) { // Extra debug check
                      logger.severe("MODEL INST IS NULL !");
                      Thread.dumpStack();
                      return;
                    }

                    if (delayedMove != null) {
                      delayedMove = null;
                      logger.fine(
                          cell.getCellID() + ": remove delayed move for: " + transform.toString());
                    }
                    avatarCharacter
                        .getModelInst()
                        .setTransform(
                            new PTransform(
                                transform.getRotation(null),
                                transform.getTranslation(null),
                                new Vector3f(1, 1, 1)));
                  } else {
                    logger.fine(cell.getCellID() + ": delaying move: " + transform.toString());
                    // we tried to move before loading the avatar.
                    // record the new position to apply when we
                    // actually load
                    delayedMove = transform;
                  }
                }
              }
            };
      }
      cell.getComponent(MovableComponent.class).addServerCellMoveListener(cellMoveListener);

      avatarUIEventListener = new AvatarUIEventListener();
      ClientContext.getInputManager().addGlobalEventListener(avatarUIEventListener);

      collisionChangeRequestListener = new CollisionChangeRequestListener();
      ClientContext.getInputManager().addGlobalEventListener(collisionChangeRequestListener);
    } else if (status == CellStatus.DISK && !increasing) {
      BoundsDebugger.getInstance().remove(this);
      ClientContext.getInputManager().removeGlobalEventListener(avatarUIEventListener);
      ClientContext.getInputManager().removeGlobalEventListener(collisionChangeRequestListener);
      cell.getComponent(MovableComponent.class).removeServerCellMoveListener(cellMoveListener);
      avatarUIEventListener = null;
      cellMoveListener = null;
      collisionChangeRequestListener = null;
    }
  }