public synchronized List<CardTerminal> list(State state) throws CardException {
   // System.out.println("list");
   if (state == null) {
     throw new NullPointerException();
   }
   try {
     String[] readerNames = SCardListReaders(contextId);
     List<CardTerminal> list = new ArrayList<CardTerminal>(readerNames.length);
     if (stateMap == null) {
       // If waitForChange() has never been called, treat event
       // queries as status queries.
       if (state == CARD_INSERTION) {
         state = CARD_PRESENT;
       } else if (state == CARD_REMOVAL) {
         state = CARD_ABSENT;
       }
     }
     for (String readerName : readerNames) {
       CardTerminal terminal = implGetTerminal(readerName);
       ReaderState readerState;
       switch (state) {
         case ALL:
           list.add(terminal);
           break;
         case CARD_PRESENT:
           if (terminal.isCardPresent()) {
             list.add(terminal);
           }
           break;
         case CARD_ABSENT:
           if (terminal.isCardPresent() == false) {
             list.add(terminal);
           }
           break;
         case CARD_INSERTION:
           readerState = stateMap.get(readerName);
           if ((readerState != null) && readerState.isInsertion()) {
             list.add(terminal);
           }
           break;
         case CARD_REMOVAL:
           readerState = stateMap.get(readerName);
           if ((readerState != null) && readerState.isRemoval()) {
             list.add(terminal);
           }
           break;
         default:
           throw new CardException("Unknown state: " + state);
       }
     }
     return Collections.unmodifiableList(list);
   } catch (PCSCException e) {
     throw new CardException("list() failed", e);
   }
 }
  public synchronized boolean waitForChange(long timeout) throws CardException {
    // System.out.println("enter WaitforChange");
    // Thread.dumpStack();

    if (timeout < 0) {
      throw new IllegalArgumentException("Timeout must not be negative: " + timeout);
    }
    if (stateMap == null) {
      // We need to initialize the state database.
      // Do that with a recursive call, which will return immediately
      // because we pass SCARD_STATE_UNAWARE.
      // After that, proceed with the real call.
      stateMap = new HashMap<String, ReaderState>();
      waitForChange(0);
    }
    if (timeout == 0) {
      timeout = TIMEOUT_INFINITE;
    }
    try {
      String[] readerNames = SCardListReaders(contextId);
      int n = readerNames.length;
      if (n == 0) {
        throw new IllegalStateException("No terminals available");
      }
      int[] status = new int[n];
      ReaderState[] readerStates = new ReaderState[n];
      for (int i = 0; i < readerNames.length; i++) {
        String name = readerNames[i];
        ReaderState state = stateMap.get(name);
        if (state == null) {
          state = new ReaderState();
        }
        readerStates[i] = state;
        status[i] = state.get();
      }
      status = SCardGetStatusChange(contextId, timeout, status, readerNames);
      stateMap.clear(); // remove any readers that are no longer available
      for (int i = 0; i < n; i++) {
        ReaderState state = readerStates[i];
        state.update(status[i]);
        stateMap.put(readerNames[i], state);
      }
      // System.out.println("exit WaitforChange");
      return true;
    } catch (PCSCException e) {
      if (e.code == SCARD_E_TIMEOUT) {
        // System.out.println("exit WaitforChange");
        return false;
      } else {
        throw new CardException("waitForChange() failed", e);
      }
    }
  }