anchor.diff:  
   ;;; SNMP-SELECT, A high-level SNMP query language.
   
  -#|
  +#| Sample Usage
   
   > (snmp-select "tcpConnTable" :from session)
   (#<TcpConnEntry 1>
  
positive.code:   (let ((entry (mib-table-entry oid)))
      (list-children entry)))
  
  (defun detect-mib-table-lines (session oid &key using)
    (declare (type session session)
             (type object-id oid))
    (list-length (snmp-walk session (or using
                                        (car (mib-table-slots oid))))))
  
negative.code:  #<TcpConnEntry 3>
   ...)
  
  ;;; Search Table
  > (snmp-select "ifTable" :from session :where `(= ,(oid "ifDescr") "eth0"))
  (#<IfEntry "eth0">)
  
  ;;; Automatic create new combined class
  > (snmp-select '("ifTable" "ifXTable") :from session
                 :where `(= (oid "ifDescr") (oid "ifName")))
  (#<IfEntry + IfXEntry 1>
   #<IfEntry + IfXEntry 2>)
  
  > (snmp-select '("IfInOctets" "IfOutOctets") :from session
                 :where `(= (oid "ifDescr") "eth0"))
  (#<Counter32 0> #<Counter32 0>)
  
  |#
  
  (defun snmp-select (identifiers &rest keys &key from &allow-other-keys)
    ;; handle string-like session first
    (if (stringp from)
        (with-open-session (session from)
          (apply #'snmp-select (list* identifiers :from session keys)))
      (apply #'snmp-select-internal (list* identifiers keys))))
  
  (defun snmp-select-internal (identifiers &key from where)
    ;; get the mib table
    (let ((table (process-identifier identifiers))
          (session from))
      (if (atom table)
          (apply #'simple-select (list* session table (if where (process-where where))))
        (error "unsupported query"))))
  
  (defun process-where (clause)
    (destructuring-bind (predicate key-part value-part) clause
      (unless (eq predicate '=)
        (error "unsupported predicate"))
      (list (oid key-part) value-part)))
  
  (defun simple-select (session table &optional key value)
    (let ((class (mib-table-class table))
          (slots (mib-table-slots table))
          (lines (detect-mib-table-lines session table :key key :value value))
          (results nil))
      (dolist (i lines (nreverse results))
        (let ((current-slots (mapcar #'(lambda (x) (oid (cons x i))) slots))
              (object (make-instance class)))
          (let ((response (snmp-get session current-slots)))
            (mapcar #'(lambda (s v)
                        (when (not (smi-p v)) ; only set valid value
                          (setf (slot-value object (oid-name s)) v)))
                    slots response)
            (push object results))))))
  
  (defgeneric process-identifier (identifier)
    (:documentation "process identifiers of snmp-select form"))
  