/**
   * <code> incarnate </code> is used for the purpose of <i>incarnating </i> servant for the
   * ObjectId the POA specified in the parameter.
   *
   * @param ok specifies the ObjectKey associated with the servant to be incarnated.
   * @param poa specifies the POA for which the ServantManager in incarnating a Servant.
   * @exception ex is thrown if incarnation needs to be performed on a different orb/poa.
   */
  protected InvokeHandler incarnate(
      FString ok,
      FString oid,
      org.omg.PortableServer.POA poa,
      POAImpl pimpl,
      IntHolder exceptionValue) {
    InvokeHandler invokeHandler = null;
    synchronized (mutex) {
      // KLUDGE:
      try {
        invokeHandler = (InvokeHandler) this.manager.incarnate(oid.getData(), poa);
      } catch (Exception fre) {
        ZenProperties.logger.log(Logger.WARN, getClass(), "incarnate", fre);
      }

      if (this.uniquenessStrategy.validate(IdUniquenessStrategy.UNIQUE_ID)
          && this.retain.servantPresent(
              (org.omg.PortableServer.Servant) invokeHandler, exceptionValue)) {
        exceptionValue.value = POARunnable.ObjAdapterException;
        return null;
      }

      POAHashMap map = pimpl.getPOAHashMap();
      // TODO assigning the wrong priority
      map.init(oid, (org.omg.PortableServer.Servant) invokeHandler, 0);

      // Add the Reference to the AOM
      this.retain.add(oid, map, exceptionValue);
      return invokeHandler;
    }
  }
  /**
   * Handle client request
   *
   * @param request ServerRequest
   * @param poa edu.uci.ece.zen.poa.POA
   * @param requests edu.uci.ece.zen.poa.SynchronizedInt
   * @return int
   */
  public void handleRequest(
      RequestMessage request,
      edu.uci.ece.zen.poa.POA poa,
      edu.uci.ece.zen.poa.SynchronizedInt requests,
      IntHolder exceptionValue) {
    exceptionValue.value = POARunnable.NoException;
    InvokeHandler invokeHandler = null;
    FString ok = request.getObjectKey();
    FString oid = pimpl.getFString();
    ObjectKeyHelper.getId(ok, oid);

    POAHashMap map = null;

    // first consult the AOM for the Request Processor
    org.omg.PortableServer.Servant servant = this.retain.getServant(oid, exceptionValue);
    if (exceptionValue.value == POARunnable.NoException) {
      if (servant != null) {
        invokeHandler = (InvokeHandler) servant;
      }
    } else {
      if (this.manager == null) {
        exceptionValue.value = POARunnable.ObjAdapterException;
        pimpl.retFString(oid);
        return;
      }

      // --- INCARNATE ---
      exceptionValue.value = POARunnable.NoException;

      invokeHandler = this.incarnate(ok, oid, poa, pimpl, exceptionValue);
      if (exceptionValue.value == POARunnable.NoException) {
        // Add the association in the AOM
        map = pimpl.getPOAHashMap();
        // TODO assigning the wrong priority
        map.init(oid, (org.omg.PortableServer.Servant) invokeHandler, 0);
        this.retain.add(oid, map, exceptionValue);
      }

      if (exceptionValue.value == POARunnable.ForwardRequestException) {
        ZenProperties.logger.log("There is a forward request exception");
        // Ask the ORB to handle the ForwardRequest Exception
        // ((edu.uci.ece.zen.poa.POA)
        // poa).getORB().handleForwardRequest(e);
        if (map != null) pimpl.freePOAHashMap(map);
        pimpl.retFString(oid);
        return; // edu.uci.ece.zen.orb.ServerRequestHandler.REQUEST_NOT_HANDLED;
      } else {
        if (map != null) pimpl.freePOAHashMap(map);
        pimpl.retFString(oid);
        exceptionValue.value = POARunnable.InternalException;
        return;
      }
    }

    map = this.retain.getHashMap(oid, exceptionValue);

    if (invokeHandler == null) {
      pimpl.retFString(oid);
      exceptionValue.value = POARunnable.InternalException;
    }

    // --- PRE-INVOKE ---
    synchronized (mutex) {
      requests.increment();
      map.incrementActiveRequests();
    }
    /*
    ((edu.uci.ece.zen.poa.POACurrent) pimpl.poaCurrent.get()).init(poa, ok,
            (org.omg.PortableServer.Servant) invokeHandler);
    */

    ResponseHandler responseHandler = new ResponseHandler(poa.getORB(), request);

    org.omg.PortableServer.Servant myServant = (org.omg.PortableServer.Servant) invokeHandler;
    CDROutputStream reply;

    // TODO Here we have DUPLICATED code
    if (this.threadPolicyStrategy instanceof ThreadPolicyStrategy.SingleThreadModelStrategy) {
      synchronized (mutex2) {
        if (request.getOperation().equals("_is_a")) {
          boolean _result = myServant._is_a(request.getCDRInputStream().read_string());
          org.omg.CORBA.portable.OutputStream _output = responseHandler.createReply();
          _output.write_boolean(_result);
          reply = (CDROutputStream) _output;
        } else if (request.getOperation().equals("_non_existent")) {
          boolean _result = myServant._non_existent();
          org.omg.CORBA.portable.OutputStream _output = responseHandler.createReply();
          _output.write_boolean(_result);
          reply = (CDROutputStream) _output;
        } else {
          reply =
              (CDROutputStream)
                  invokeHandler._invoke(
                      request.getOperation().toString(),
                      (org.omg.CORBA.portable.InputStream) request.getCDRInputStream(),
                      responseHandler);
        }
      }
    } else {
      if (request.getOperation().equals("_is_a")) {
        boolean _result = myServant._is_a(request.getCDRInputStream().read_string());
        org.omg.CORBA.portable.OutputStream _output = responseHandler.createReply();
        _output.write_boolean(_result);
        reply = (CDROutputStream) _output;
      } else if (request.getOperation().equals("_non_existent")) {
        boolean _result = myServant._non_existent();
        org.omg.CORBA.portable.OutputStream _output = responseHandler.createReply();
        _output.write_boolean(_result);
        reply = (CDROutputStream) _output;
      } else {
        reply =
            (CDROutputStream)
                invokeHandler._invoke(
                    request.getOperation().toString(),
                    (org.omg.CORBA.portable.InputStream) request.getCDRInputStream(),
                    responseHandler);
      }
    }

    synchronized (mutex) {
      requests.decrementAndNotifyAll(pimpl.self.processingState == POA.DESTRUCTION_APPARANT);
      try {
        map.decrementActiveRequestsAndDeactivate();
      } catch (Exception ex) {
      }
    }

    // send back reply
    // reply.sendUsing(request.getTransport());

    pimpl.retFString(oid);
    return;
  }