@Override
  public synchronized void updateEntry(final String key, final HttpCacheUpdateCallback callback)
      throws IOException, HttpCacheUpdateException {
    int numRetries = 0;
    do {
      final Element oldElement = cache.get(key);

      HttpCacheEntry existingEntry = null;
      if (oldElement != null) {
        final byte[] data = (byte[]) oldElement.getValue();
        existingEntry = serializer.readFrom(new ByteArrayInputStream(data));
      }

      final HttpCacheEntry updatedEntry = callback.update(existingEntry);

      if (existingEntry == null) {
        putEntry(key, updatedEntry);
        return;
      } else {
        // Attempt to do a CAS replace, if we fail then retry
        // While this operation should work fine within this instance, multiple instances
        //  could trample each others' data
        final ByteArrayOutputStream bos = new ByteArrayOutputStream();
        serializer.writeTo(updatedEntry, bos);
        final Element newElement = new Element(key, bos.toByteArray());
        if (cache.replace(oldElement, newElement)) {
          return;
        } else {
          numRetries++;
        }
      }
    } while (numRetries <= maxUpdateRetries);
    throw new HttpCacheUpdateException("Failed to update");
  }
  @Test
  public void testCASOperationsNotSupported() throws Exception {
    LOG.info("START TEST");

    final Ehcache cache1 = manager1.getEhcache(cacheName);
    final Ehcache cache2 = manager2.getEhcache(cacheName);
    final Ehcache cache3 = manager3.getEhcache(cacheName);
    final Ehcache cache4 = manager4.getEhcache(cacheName);

    try {
      cache1.putIfAbsent(new Element("foo", "poo"));
      throw new AssertionError("CAS operation should have failed.");
    } catch (CacheException ce) {
      assertEquals(true, ce.getMessage().contains("CAS"));
    }

    try {
      cache2.removeElement(new Element("foo", "poo"));
      throw new AssertionError("CAS operation should have failed.");
    } catch (CacheException ce) {
      assertEquals(true, ce.getMessage().contains("CAS"));
    }

    try {
      cache3.replace(new Element("foo", "poo"));
      throw new AssertionError("CAS operation should have failed.");
    } catch (CacheException ce) {
      assertEquals(true, ce.getMessage().contains("CAS"));
    }

    try {
      cache4.replace(new Element("foo", "poo"), new Element("foo", "poo2"));
      throw new AssertionError("CAS operation should have failed.");
    } catch (CacheException ce) {
      assertEquals(true, ce.getMessage().contains("CAS"));
    }

    LOG.info("END TEST");
  }
  @Override
  protected void doReceive(Message message) throws Exception {
    PortalCacheClusterEvent portalCacheClusterEvent =
        (PortalCacheClusterEvent) message.getPayload();

    if (portalCacheClusterEvent == null) {
      if (_log.isWarnEnabled()) {
        _log.warn("Payload is null");
      }

      return;
    }

    String cacheName = portalCacheClusterEvent.getCacheName();

    Ehcache ehcache = _portalCacheManager.getEhcache(cacheName);

    if (ehcache == null) {
      ehcache = _hibernateCacheManager.getEhcache(cacheName);
    }

    if (ehcache != null) {
      PortalCacheClusterEventType portalCacheClusterEventType =
          portalCacheClusterEvent.getEventType();

      if (portalCacheClusterEventType.equals(PortalCacheClusterEventType.REMOVEALL)) {

        ehcache.removeAll(true);
      } else if (portalCacheClusterEventType.equals(PortalCacheClusterEventType.PUT)
          || portalCacheClusterEventType.equals(PortalCacheClusterEventType.UPDATE)) {

        Serializable elementKey = portalCacheClusterEvent.getElementKey();
        Serializable elementValue = portalCacheClusterEvent.getElementValue();

        if (elementValue == null) {
          ehcache.remove(portalCacheClusterEvent.getElementKey(), true);
        } else {
          Element oldElement = ehcache.get(elementKey);
          Element newElement = new Element(elementKey, elementValue);

          if (oldElement != null) {
            ehcache.replace(newElement);
          } else {
            ehcache.put(newElement);
          }
        }
      } else {
        ehcache.remove(portalCacheClusterEvent.getElementKey(), true);
      }
    }
  }