@Override
    public void fileCleanStatusChanged(FileChangeEvent evt) {
      Object source = evt.getSource();
      if (source instanceof InitTableModel) {
        if (LOG.isLoggable(Level.FINE)) {
          LOG.fine("ActorTableModel " + evt.isClean());
        }
        tableIsClean = evt.isClean();
      } else if (source instanceof GroupTree) {
        if (LOG.isLoggable(Level.FINE)) {
          LOG.fine("GroupTree " + evt.isClean());
        }
        treeIsClean = evt.isClean();
      } else {
        if (LOG.isLoggable(Level.WARNING)) {
          LOG.warning("UNKNOWN " + evt.isClean());
        }
      }

      if (tableIsClean && treeIsClean) {
        if (saveAsFile != null) {
          setTitle("Groups Manager - " + saveAsFile.getName());
        } else {
          setTitle("Groups Manager");
        }
      } else {
        if (saveAsFile != null) {
          setTitle("Groups Manager - " + saveAsFile.getName() + "*");
        } else {
          setTitle("Groups Manager *");
        }
      }
    }
 private void processPayload(byte[] compressedPayload) {
   byte[] payload = PayloadUtil.ungzip(compressedPayload);
   String rmiUrls = new String(payload);
   if (self(rmiUrls)) {
     return;
   }
   rmiUrls = rmiUrls.trim();
   if (LOG.isLoggable(Level.FINE)) {
     LOG.fine("rmiUrls received " + rmiUrls);
   }
   processRmiUrls(rmiUrls);
 }
    @Override
    public void run() {
      try {
        // 检查
        check();
      } catch (Exception e) {

        // eat and log exception
        if (LOG.isLoggable(Level.FINE)) {
          LOG.fine("error occured by running check: " + e.toString());
        }
      }
    }
    /**
     * Synch.
     *
     * @throws SearchException the search exception
     */
    public void synch() throws SearchException {

      if (__suppliedCriteria == __sessionCriteria) {
        return;
      }
      try {
        __sessionCriteria.loadSearchCriteria(__suppliedCriteria.toDom());
      } catch (ConcurrentModificationException e) {
        // This sometimes occurs especially when the user presesses the search
        // button multiple times at a very fast pace
        LOG.fine("Saving session failed" + e.getMessage());
      }
    }
 /** ... */
 private static Map<String, String> parseOverrideProperty() throws PackageException {
   Map<String, String> res = new HashMap<String, String>();
   String prop = System.getProperty(OVERRIDE_PROP);
   if (prop == null || "".equals(prop)) {
     return res;
   }
   LOG.fine("Property {0} value is: {1}", OVERRIDE_PROP, prop);
   for (String override : prop.split(",")) {
     // ignore empty one (so allow the prop ",something else")
     if (override == null || "".equals(override)) {
       continue;
     }
     String[] split = override.split("\\|");
     if (split == null || split.length != 2) {
       throw new PackageException("Wrong resolve value: " + prop);
     }
     res.put(split[0], split[1]);
   }
   return res;
 }
    @Override
    public void processResult(int rawReturnCode, String notUsed, Object parent, String notUsed2) {

      KeeperException.Code returnCode = KeeperException.Code.get(rawReturnCode);
      ClaimedCoordinate claimedCoordinate = (ClaimedCoordinate) parent;
      LOG.fine(
          "Claim callback with "
              + returnCode.name()
              + " "
              + claimedCoordinate.path
              + " synched: "
              + isSynchronizedWithZooKeeper.get()
              + " thread: "
              + this);
      switch (returnCode) {
          // The claim was successful. This means that the node was created. We need to
          // populate the status and endpoints.
        case OK:

          // We should be the first one to write to the new node, or fail.
          // This requires that the first version is 0, have not seen this documented
          // but it should be a fair assumption and is verified by unit tests.
          synchronized (lastStatusVersionMonitor) {
            lastStatusVersion = 0;
          }

          // We need to set this to synced or updateCoordinateData will complain.
          // updateCoordinateData will set it to out-of-sync in case of problems.
          isSynchronizedWithZooKeeper.set(true);

          try {
            registerWatcher();
          } catch (CloudnameException e) {
            LOG.fine(
                "Failed register watcher after claim. Going to state out of sync: "
                    + e.getMessage());

            isSynchronizedWithZooKeeper.set(false);
            return;

          } catch (InterruptedException e) {

            LOG.fine("Interrupted while setting up new watcher. Going to state out of sync.");
            isSynchronizedWithZooKeeper.set(false);
            return;
          }
          // No exceptions, let's celebrate with a log message.
          LOG.info("Claim processed ok, path: " + path);
          claimedCoordinate.sendEventToCoordinateListener(
              CoordinateListener.Event.COORDINATE_OK, "claimed");
          return;

        case NODEEXISTS:
          // Someone has already claimed the coordinate. It might have been us in a
          // different thread. If we already have claimed the coordinate then don't care.
          // Else notify the client. If everything is fine, this is not a true negative,
          // so ignore it. It might happen if two attempts to tryClaim the coordinate run
          // in parallel.
          if (isSynchronizedWithZooKeeper.get() && started.get()) {
            LOG.fine("Everything is fine, ignoring NODEEXISTS message, path: " + path);
            return;
          }

          LOG.info("Claimed fail, node already exists, will retry: " + path);
          claimedCoordinate.sendEventToCoordinateListener(
              CoordinateListener.Event.NOT_OWNER, "Node already exists.");
          LOG.info("isSynchronizedWithZooKeeper: " + isSynchronizedWithZooKeeper.get());
          checkVersion.set(true);
          return;
        case NONODE:
          LOG.info("Could not claim due to missing coordinate, path: " + path);
          claimedCoordinate.sendEventToCoordinateListener(
              CoordinateListener.Event.NOT_OWNER,
              "No node on claiming coordinate: " + returnCode.name());
          return;

        default:
          // Random problem, report the problem to the client.
          claimedCoordinate.sendEventToCoordinateListener(
              CoordinateListener.Event.NO_CONNECTION_TO_STORAGE,
              "Could not reclaim coordinate. Return code: " + returnCode.name());
          return;
      }
    }
    /** Enqueuer thread main method */
    @Override
    public void run() {
      try {
        /* Mute line initially to prevent clicks */
        setVolume(Float.NEGATIVE_INFINITY);

        /* Start the line */
        // m_line.start();
        // start the audio track
        audioTrack.play();

        LOG.info("Audio Track started !!!");

        boolean lineMuted = true;
        boolean didWarnGap = false;
        while (!closing) {
          if (!frameQueue.isEmpty()) {
            /* Queue filled */

            /* If the gap between the next packet and the end of line is
             * negligible (less than one packet), we write it to the line.
             * Otherwise, we fill the line buffer with silence and hope for
             * further packets to appear in the queue
             */
            final long entryFrameTime = frameQueue.firstKey();
            final long entryLineTime = convertFrameToLineTime(entryFrameTime);
            final long gapFrames = entryLineTime - getNextLineTime();

            // LOG.info("** gapFrames: " + gapFrames + " packetSizeFrames: " +  packetSizeFrames);

            if (gapFrames < -packetSizeFrames) {
              /* Too late for playback */
              LOG.warning(
                  "Audio data was scheduled for playback "
                      + (-gapFrames)
                      + " frames ago, skipping");
              frameQueue.remove(entryFrameTime);
              continue;
            } else if (gapFrames < packetSizeFrames) {
              /* Negligible gap between packet and line end. Prepare packet for playback */
              didWarnGap = false;

              /* Unmute line in case it was muted previously */
              if (lineMuted) {
                LOG.info("Audio data available, un-muting line");

                lineMuted = false;
                applyVolume();
              } else if (getVolume() != getRequestedVolume()) {
                applyVolume();
              }

              /* Get sample data and do sanity checks */
              final byte[] nextPlaybackSamples = frameQueue.remove(entryFrameTime);
              int nextPlaybackSamplesLength = nextPlaybackSamples.length;
              if (nextPlaybackSamplesLength % bytesPerFrame != 0) {
                LOG.severe(
                    "Audio data contains non-integral number of frames, ignore last "
                        + (nextPlaybackSamplesLength % bytesPerFrame)
                        + " bytes");
                nextPlaybackSamplesLength -= nextPlaybackSamplesLength % bytesPerFrame;
              }

              /* Append packet to line */
              LOG.finest(
                  "Audio data containing "
                      + nextPlaybackSamplesLength / bytesPerFrame
                      + " frames for playback time "
                      + entryFrameTime
                      + " found in queue, appending to the output line");

              appendFrames(nextPlaybackSamples, 0, nextPlaybackSamplesLength, entryLineTime);

              continue;
            } else {
              /* Gap between packet and line end. Warn */
              if (!didWarnGap) {
                didWarnGap = true;
                LOG.warning(
                    "Audio data missing for frame time "
                        + getNextLineTime()
                        + " (currently "
                        + gapFrames
                        + " frames), writing "
                        + packetSizeFrames
                        + " frames of silence");
              }
            }
          } else {
            /* Queue empty */

            if (!lineMuted) {
              lineMuted = true;
              setVolume(Float.NEGATIVE_INFINITY);
              LOG.fine(
                  "Audio data ended at frame time "
                      + getNextLineTime()
                      + ", writing "
                      + packetSizeFrames
                      + " frames of silence and muted line");
            }
          }

          appendSilence(packetSizeFrames);
        }

        // TODO: I don't think we need the appendSilence anymore when using Android API, but will
        // evaluate that later during tests
        /* Before we exit, we fill the line's buffer with silence. This should prevent
         * noise from being output while the line is being stopped
         */
        // appendSilence(m_line.available() / m_bytesPerFrame);
      } catch (final Throwable e) {
        LOG.log(Level.SEVERE, "Audio output thread died unexpectedly", e);
      } finally {
        setVolume(Float.NEGATIVE_INFINITY);
        audioTrack.stop();
        audioTrack.release();
        // m_line.stop();
        // m_line.close();
      }
    }