/**
   * Checks whether an SNMP SET request can be successfully performed.
   *
   * <p>For each variable in the subrequest, this method calls checkSetAccess() on the meta object,
   * and then tries to invoke the check<i>AttributeName</i>() method on the MBean. If this method is
   * not defined then it is assumed that the SET won't fail.
   *
   * <p><b><i> This method is called internally by <code>mibgen</code> generated objects and you
   * should never need to call it directly. </i></b>
   *
   * @param meta The metadata object impacted by the subrequest
   * @param name The ObjectName of the MBean impacted by this subrequest
   * @param req The SNMP subrequest to execute on the MBean
   * @param depth The depth of the SNMP object in the OID tree.
   * @exception SnmpStatusException if the requested SET operation must be rejected. Raising an
   *     exception will abort the request. <br>
   *     Exceptions should never be raised directly, but only by means of <code>
   * req.registerCheckException(<i>VariableId</i>,<i>SnmpStatusException</i>)
   * </code>
   */
  public void check(SnmpGenericMetaServer meta, ObjectName name, SnmpMibSubRequest req, int depth)
      throws SnmpStatusException {

    final Object data = req.getUserData();

    for (Enumeration e = req.getElements(); e.hasMoreElements(); ) {
      final SnmpVarBind var = (SnmpVarBind) e.nextElement();
      try {
        final long id = var.oid.getOidArc(depth);
        // call meta.check() here, and meta.check will call check()
        check(meta, name, var.value, id, data);
      } catch (SnmpStatusException x) {
        req.registerCheckException(var, x);
      }
    }
  }
  /**
   * Execute an SNMP SET request.
   *
   * <p>This method first builds the list of attributes that need to be set on the MBean and then
   * calls setAttributes() on the MBean server. Then it updates the SnmpMibSubRequest with the new
   * values retrieved from the MBean.
   *
   * <p>The SNMP metadata information is obtained through the given <code>meta</code> object, which
   * usually is an instance of a <code>mibgen</code> generated class.
   *
   * <p><b><i> This method is called internally by <code>mibgen</code> generated objects and you
   * should never need to call it directly. </i></b>
   *
   * @param meta The metadata object impacted by the subrequest
   * @param name The ObjectName of the MBean impacted by this subrequest
   * @param req The SNMP subrequest to execute on the MBean
   * @param depth The depth of the SNMP object in the OID tree.
   * @exception SnmpStatusException whenever an SNMP exception must be raised. Raising an exception
   *     will abort the request. <br>
   *     Exceptions should never be raised directly, but only by means of <code>
   * req.registerGetException(<i>VariableId</i>,<i>SnmpStatusException</i>)
   * </code>
   */
  public void set(SnmpGenericMetaServer meta, ObjectName name, SnmpMibSubRequest req, int depth)
      throws SnmpStatusException {

    final int size = req.getSize();
    final AttributeList attList = new AttributeList(size);
    final String[] nameList = new String[size];
    final SnmpVarBind[] varList = new SnmpVarBind[size];
    final long[] idList = new long[size];
    int i = 0;

    for (Enumeration e = req.getElements(); e.hasMoreElements(); ) {
      final SnmpVarBind var = (SnmpVarBind) e.nextElement();
      try {
        final long id = var.oid.getOidArc(depth);
        final String attname = meta.getAttributeName(id);
        final Object attvalue = meta.buildAttributeValue(id, var.value);
        final Attribute att = new Attribute(attname, attvalue);
        attList.add(att);
        nameList[i] = attname;
        varList[i] = var;
        idList[i] = id;
        i++;
      } catch (SnmpStatusException x) {
        req.registerSetException(var, x);
      }
    }

    AttributeList result = null;
    int errorCode = SnmpStatusException.noAccess;

    try {
      result = server.setAttributes(name, attList);
    } catch (InstanceNotFoundException f) {
      result = new AttributeList();
      errorCode = SnmpStatusException.snmpRspInconsistentName;
    } catch (ReflectionException r) {
      errorCode = SnmpStatusException.snmpRspInconsistentName;
      result = new AttributeList();
    } catch (Exception x) {
      result = new AttributeList();
    }

    final Iterator it = result.iterator();

    for (int j = 0; j < i; j++) {
      if (!it.hasNext()) {
        final SnmpStatusException x = new SnmpStatusException(errorCode);
        req.registerSetException(varList[j], x);
        continue;
      }

      final Attribute att = (Attribute) it.next();

      while ((j < i) && (!nameList[j].equals(att.getName()))) {
        final SnmpStatusException x = new SnmpStatusException(SnmpStatusException.noAccess);
        req.registerSetException(varList[j], x);
        j++;
      }

      if (j == i) break;

      try {
        varList[j].value = meta.buildSnmpValue(idList[j], att.getValue());
      } catch (SnmpStatusException x) {
        req.registerSetException(varList[j], x);
      }
    }
  }
  /**
   * Execute an SNMP GET request.
   *
   * <p>This method first builds the list of attributes that need to be retrieved from the MBean and
   * then calls getAttributes() on the MBean server. Then it updates the SnmpMibSubRequest with the
   * values retrieved from the MBean.
   *
   * <p>The SNMP metadata information is obtained through the given <code>meta</code> object, which
   * usually is an instance of a <code>mibgen</code> generated class.
   *
   * <p><b><i> This method is called internally by <code>mibgen</code> generated objects and you
   * should never need to call it directly. </i></b>
   *
   * @param meta The metadata object impacted by the subrequest
   * @param name The ObjectName of the MBean impacted by this subrequest
   * @param req The SNMP subrequest to execute on the MBean
   * @param depth The depth of the SNMP object in the OID tree.
   * @exception SnmpStatusException whenever an SNMP exception must be raised. Raising an exception
   *     will abort the request.<br>
   *     Exceptions should never be raised directly, but only by means of <code>
   * req.registerGetException(<i>VariableId</i>,<i>SnmpStatusException</i>)
   * </code>
   */
  public void get(SnmpGenericMetaServer meta, ObjectName name, SnmpMibSubRequest req, int depth)
      throws SnmpStatusException {

    // java.lang.System.out.println(">>>>>>>>> GET " + name);

    final int size = req.getSize();
    final Object data = req.getUserData();
    final String[] nameList = new String[size];
    final SnmpVarBind[] varList = new SnmpVarBind[size];
    final long[] idList = new long[size];
    int i = 0;

    for (Enumeration e = req.getElements(); e.hasMoreElements(); ) {
      final SnmpVarBind var = (SnmpVarBind) e.nextElement();
      try {
        final long id = var.oid.getOidArc(depth);
        nameList[i] = meta.getAttributeName(id);
        varList[i] = var;
        idList[i] = id;

        // Check the access rights according to the MIB.
        // The MBean might be less restrictive (have a getter
        // while the MIB defines the variable as AFN)
        //
        meta.checkGetAccess(id, data);

        // java.lang.System.out.println(nameList[i] + " added.");
        i++;
      } catch (SnmpStatusException x) {
        // java.lang.System.out.println("exception for " + nameList[i]);
        // x.printStackTrace();
        req.registerGetException(var, x);
      }
    }

    AttributeList result = null;
    int errorCode = SnmpStatusException.noSuchInstance;

    try {
      result = server.getAttributes(name, nameList);
    } catch (InstanceNotFoundException f) {
      // java.lang.System.out.println(name + ": instance not found.");
      // f.printStackTrace();
      result = new AttributeList();
    } catch (ReflectionException r) {
      // java.lang.System.out.println(name + ": reflexion error.");
      // r.printStackTrace();
      result = new AttributeList();
    } catch (Exception x) {
      result = new AttributeList();
    }

    final Iterator it = result.iterator();

    for (int j = 0; j < i; j++) {
      if (!it.hasNext()) {
        // java.lang.System.out.println(name + "variable[" + j +
        //                           "] absent");
        final SnmpStatusException x = new SnmpStatusException(errorCode);
        req.registerGetException(varList[j], x);
        continue;
      }

      final Attribute att = (Attribute) it.next();

      while ((j < i) && (!nameList[j].equals(att.getName()))) {
        // java.lang.System.out.println(name + "variable[" +j +
        //                           "] not found");
        final SnmpStatusException x = new SnmpStatusException(errorCode);
        req.registerGetException(varList[j], x);
        j++;
      }

      if (j == i) break;

      try {
        varList[j].value = meta.buildSnmpValue(idList[j], att.getValue());
      } catch (SnmpStatusException x) {
        req.registerGetException(varList[j], x);
      }
      // java.lang.System.out.println(att.getName() + " retrieved.");
    }
    // java.lang.System.out.println(">>>>>>>>> END GET");
  }