private IMode getMode(char[] password, int state) {
      String s = properties.get("salt");
      if (s == null) {
         throw new IllegalArgumentException("no salt");
      }
      byte[] salt = Util.toBytesFromString(s);
      IBlockCipher cipher = CipherFactory.getInstance(properties.get("cipher"));
      if (cipher == null) {
         throw new IllegalArgumentException("no such cipher: " + properties.get("cipher"));
      }
      int blockSize = cipher.defaultBlockSize();
      if (properties.containsKey("block-size")) {
         try {
            blockSize = Integer.parseInt(properties.get("block-size"));
         } catch (NumberFormatException nfe) {
            throw new IllegalArgumentException("bad block size: " + nfe.getMessage());
         }
      }
      IMode mode = ModeFactory.getInstance(properties.get("mode"), cipher, blockSize);
      if (mode == null) {
         throw new IllegalArgumentException("no such mode: " + properties.get("mode"));
      }

      HashMap pbAttr = new HashMap();
      pbAttr.put(IPBE.PASSWORD, password);
      pbAttr.put(IPBE.SALT, salt);
      pbAttr.put(IPBE.ITERATION_COUNT, ITERATION_COUNT);
      IRandom kdf = PRNGFactory.getInstance("PBKDF2-HMAC-SHA");
      kdf.init(pbAttr);

      int keylen = 0;
      if (!properties.containsKey("keylen")) {
         throw new IllegalArgumentException("no key length");
      }
      try {
         keylen = Integer.parseInt(properties.get("keylen"));
      } catch (NumberFormatException nfe) {
      }
      byte[] dk = new byte[keylen];
      byte[] iv = new byte[blockSize];
      try {
         kdf.nextBytes(dk, 0, keylen);
         kdf.nextBytes(iv, 0, blockSize);
      } catch (LimitReachedException shouldNotHappen) {
         throw new Error(shouldNotHappen.toString());
      }
      HashMap modeAttr = new HashMap();
      modeAttr.put(IMode.KEY_MATERIAL, dk);
      modeAttr.put(IMode.STATE, new Integer(state));
      modeAttr.put(IMode.IV, iv);
      try {
         mode.init(modeAttr);
      } catch (InvalidKeyException ike) {
         throw new IllegalArgumentException(ike.toString());
      }
      return mode;
   }