public void doFetch() {
   synchronized (this) {
     if (consumers == null) {
       awaitingFetch = false;
       return;
     }
   }
   ImageDecoder imgd = getDecoder();
   if (imgd == null) {
     badDecoder();
   } else {
     setDecoder(imgd);
     try {
       imgd.produceImage();
     } catch (IOException e) {
       e.printStackTrace();
       // the finally clause will send an error.
     } catch (ImageFormatException e) {
       e.printStackTrace();
       // the finally clause will send an error.
     } finally {
       removeDecoder(imgd);
       if (Thread.currentThread().isInterrupted() || !Thread.currentThread().isAlive()) {
         errorAllConsumers(imgd.queue, true);
       } else {
         errorAllConsumers(imgd.queue, false);
       }
     }
   }
 }
 public synchronized boolean isConsumer(ImageConsumer ic) {
   for (ImageDecoder id = decoders; id != null; id = id.next) {
     if (id.isConsumer(ic)) {
       return true;
     }
   }
   return ImageConsumerQueue.isConsumer(consumers, ic);
 }
 private synchronized void removeDecoder(ImageDecoder mydecoder) {
   doneDecoding(mydecoder);
   ImageDecoder idprev = null;
   for (ImageDecoder id = decoders; id != null; id = id.next) {
     if (id == mydecoder) {
       if (idprev == null) {
         decoders = id.next;
       } else {
         idprev.next = id.next;
       }
       break;
     }
     idprev = id;
   }
 }
 synchronized void addConsumer(ImageConsumer ic, boolean produce) {
   checkSecurity(null, false);
   for (ImageDecoder id = decoders; id != null; id = id.next) {
     if (id.isConsumer(ic)) {
       // This consumer is already being fed.
       return;
     }
   }
   ImageConsumerQueue cq = consumers;
   while (cq != null && cq.consumer != ic) {
     cq = cq.next;
   }
   if (cq == null) {
     cq = new ImageConsumerQueue(this, ic);
     cq.next = consumers;
     consumers = cq;
   } else {
     if (!cq.secure) {
       Object context = null;
       SecurityManager security = System.getSecurityManager();
       if (security != null) {
         context = security.getSecurityContext();
       }
       if (cq.securityContext == null) {
         cq.securityContext = context;
       } else if (!cq.securityContext.equals(context)) {
         // If there are two different security contexts that both
         // have a handle on the same ImageConsumer, then there has
         // been a security breach and whether or not they trade
         // image data is small fish compared to what they could be
         // trading.  Throw a Security exception anyway...
         errorConsumer(cq, false);
         throw new SecurityException("Applets are trading image data!");
       }
     }
     cq.interested = true;
   }
   if (produce && decoder == null) {
     startProduction();
   }
 }
 private void setDecoder(ImageDecoder mydecoder) {
   ImageConsumerQueue cq;
   synchronized (this) {
     mydecoder.next = decoders;
     decoders = mydecoder;
     decoder = mydecoder;
     cq = consumers;
     mydecoder.queue = cq;
     consumers = null;
     awaitingFetch = false;
   }
   while (cq != null) {
     if (cq.interested) {
       // Now that there is a decoder, security may have changed
       // so reverify it here, just in case.
       if (!checkSecurity(cq.securityContext, true)) {
         errorConsumer(cq, false);
       }
     }
     cq = cq.next;
   }
 }
 public synchronized void removeConsumer(ImageConsumer ic) {
   for (ImageDecoder id = decoders; id != null; id = id.next) {
     id.removeConsumer(ic);
   }
   consumers = ImageConsumerQueue.removeConsumer(consumers, ic, false);
 }