/**
  * Creates an extended response from the supplied response data.
  *
  * @param requestOID of the extended request
  * @param responseOID of the extended response
  * @param encoded BER encoding of the extended response
  * @return extended response
  */
 public static ExtendedResponse<?> createExtendedResponse(
     final String requestOID, final String responseOID, final byte[] encoded) {
   ExtendedResponse<?> res;
   if (PasswordModifyRequest.OID.equals(requestOID)) {
     res = new PasswordModifyResponse();
     if (encoded != null) {
       res.decode(encoded);
     }
   } else if (WhoAmIRequest.OID.equals(requestOID)) {
     res = new WhoAmIResponse();
     if (encoded != null) {
       res.decode(encoded);
     }
   } else if (CancelRequest.OID.equals(requestOID)) {
     res = new CancelResponse();
   } else if (FastBindRequest.OID.equals(requestOID)) {
     res = new FastBindResponse();
   } else {
     throw new IllegalArgumentException("Unknown OID: " + responseOID);
   }
   return res;
 }
  /**
   * Perform the LDAP EXTENDED operation and send the result back to the client.
   *
   * @param objFactory The object factory for this operation.
   * @param extendedRequest The extended request for this operation.
   * @param controls Any required controls (e.g. for proxy authz).
   * @return The result of the extended operation.
   * @throws IOException If an I/O problem occurs.
   * @throws LDAPException If an error occurs while interacting with an LDAP element.
   * @throws ASN1Exception If an error occurs while interacting with an ASN.1 element.
   */
  public ExtendedResponse doOperation(
      ObjectFactory objFactory,
      ExtendedRequest extendedRequest,
      List<org.opends.server.types.Control> controls)
      throws IOException, LDAPException, ASN1Exception {
    ExtendedResponse extendedResponse = objFactory.createExtendedResponse();
    extendedResponse.setRequestID(extendedRequest.getRequestID());

    String requestName = extendedRequest.getRequestName();
    Object value = extendedRequest.getRequestValue();
    ByteString asnValue = ByteStringUtility.convertValue(value);

    // Create and send the LDAP request to the server.
    ProtocolOp op = new ExtendedRequestProtocolOp(requestName, asnValue);
    LDAPMessage msg = new LDAPMessage(DSMLServlet.nextMessageID(), op, controls);
    connection.getLDAPWriter().writeMessage(msg);

    // Read and decode the LDAP response from the server.
    LDAPMessage responseMessage = connection.getLDAPReader().readMessage();

    ExtendedResponseProtocolOp extendedOp = responseMessage.getExtendedResponseProtocolOp();
    int resultCode = extendedOp.getResultCode();
    Message errorMessage = extendedOp.getErrorMessage();

    // Set the result code and error message for the DSML response.
    extendedResponse.setResponseName(extendedOp.getOID());

    ByteString rawValue = extendedOp.getValue();
    value = null;
    if (rawValue != null) {
      if (responseIsString(requestName)) {
        value = rawValue.toString();
      } else {
        value = rawValue.toByteArray();
      }
    }
    extendedResponse.setResponse(value);
    extendedResponse.setErrorMessage(errorMessage != null ? errorMessage.toString() : null);
    ResultCode code = ResultCodeFactory.create(objFactory, resultCode);
    extendedResponse.setResultCode(code);

    return extendedResponse;
  }