public static final int[] decodeOID(BERInputStream is, MutableByte type)
      throws IOException
  {
    /*
     * ASN.1 objid ::= 0x06 asnlength subidentifier {subidentifier}*
     * subidentifier ::= {leadingbyte}* lastbyte
     * leadingbyte ::= 1 7bitvalue
     * lastbyte ::= 0 7bitvalue
     */
    int subidentifier;
    int length;

    // get the type
    type.setValue((byte)is.read());
    if (type.value != 0x06) {
      throw new IOException("Wrong type. Not an OID: "+type.value+
                            getPositionMessage(is));
    }
    length = decodeLength(is);

    int[] oid = new int[length+2];
    /* Handle invalid object identifier encodings of the form 06 00 robustly */
    if (length == 0) {
      oid[0] = oid[1] = 0;
    }
    int pos = 1;
    while (length > 0){
      subidentifier = 0;
      int b;
      do {	/* shift and add in low order 7 bits */
        int next = is.read();
        if (next < 0) {
          throw new IOException("Unexpected end of input stream" +
                                getPositionMessage(is));
        }
        b = next & 0xFF;
        subidentifier = (subidentifier << 7) + (b & ~ASN_BIT8);
        length--;
      } while ((length > 0) && ((b & ASN_BIT8) != 0));	/* last byte has high bit clear */
      oid[pos++] = subidentifier;
    }

    /*
    * The first two subidentifiers are encoded into the first component
    * with the value (X * 40) + Y, where:
    *	X is the value of the first subidentifier.
    *  Y is the value of the second subidentifier.
    */
    subidentifier = oid[1];
    if (subidentifier == 0x2B){
      oid[0] = 1;
      oid[1] = 3;
    }
    else {
      oid[1] = (subidentifier % 40);
      oid[0] = ((subidentifier - oid[1]) / 40);
    }
    if (pos < 2) {
      pos = 2;
    }
    int[] value = new int[pos];
    System.arraycopy(oid, 0, value, 0, pos);
    return value;
  }