text:
package org.ehcache.impl.internal.store.offheap;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

import org.ehcache.Cache;
import org.ehcache.config.EvictionAdvisor;
import org.ehcache.core.events.StoreEventDispatcher;
import org.ehcache.core.events.StoreEventSink;
import org.ehcache.core.spi.store.StoreAccessException;
import org.ehcache.expiry.Duration;
import org.ehcache.expiry.Expiry;
import org.ehcache.core.spi.function.BiFunction;
import org.ehcache.core.spi.function.Function;
import org.ehcache.core.spi.function.NullaryFunction;
import org.ehcache.core.spi.time.TimeSource;
import org.ehcache.impl.internal.store.offheap.factories.EhcacheSegmentFactory;
import org.ehcache.core.spi.store.Store;
import org.ehcache.core.spi.store.events.StoreEventSource;
import org.ehcache.core.spi.store.tiering.AuthoritativeTier;
import org.ehcache.core.spi.store.tiering.CachingTier;
import org.ehcache.core.spi.store.tiering.LowerCachingTier;
import org.ehcache.core.statistics.AuthoritativeTierOperationOutcomes;
import org.ehcache.core.statistics.LowerCachingTierOperationsOutcome;
import org.ehcache.core.statistics.StoreOperationOutcomes;
import org.ehcache.impl.internal.store.BinaryValueHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terracotta.offheapstore.exceptions.OversizeMappingException;
import org.terracotta.statistics.StatisticsManager;
import org.terracotta.statistics.observer.OperationObserver;

import static org.ehcache.core.exceptions.StorePassThroughException.handleRuntimeException;
import static org.ehcache.core.internal.util.ValueSuppliers.supplierOf;
import org.terracotta.context.annotations.ContextAttribute;
import static org.terracotta.statistics.StatisticBuilder.operation;

public abstract class AbstractOffHeapStore<K, V> implements AuthoritativeTier<K, V>, LowerCachingTier<K, V> {

  private static final Logger LOG = LoggerFactory.getLogger(AbstractOffHeapStore.class);

  private static final CachingTier.InvalidationListener NULL_INVALIDATION_LISTENER = new CachingTier.InvalidationListener() {
    @Override
    public void onInvalidation(Object key, ValueHolder valueHolder) {
      // Do nothing
    }
  };

  private final Class<K> keyType;
  private final Class<V> valueType;
  private final TimeSource timeSource;
  private final StoreEventDispatcher<K, V> eventDispatcher;

  private final Expiry<? super K, ? super V> expiry;

  private final OperationObserver<StoreOperationOutcomes.GetOutcome> getObserver;
  private final OperationObserver<StoreOperationOutcomes.PutOutcome> putObserver;
  private final OperationObserver<StoreOperationOutcomes.PutIfAbsentOutcome> putIfAbsentObserver;
  private final OperationObserver<StoreOperationOutcomes.RemoveOutcome> removeObserver;
  private final OperationObserver<StoreOperationOutcomes.ConditionalRemoveOutcome> conditionalRemoveObserver;
  private final OperationObserver<StoreOperationOutcomes.ReplaceOutcome> replaceObserver;
  private final OperationObserver<StoreOperationOutcomes.ConditionalReplaceOutcome> conditionalReplaceObserver;
  private final OperationObserver<StoreOperationOutcomes.ComputeOutcome> computeObserver;
  private final OperationObserver<StoreOperationOutcomes.ComputeIfAbsentOutcome> computeIfAbsentObserver;
  private final OperationObserver<StoreOperationOutcomes.EvictionOutcome> evictionObserver;
  private final OperationObserver<StoreOperationOutcomes.ExpirationOutcome> expirationObserver;

  private final OperationObserver<AuthoritativeTierOperationOutcomes.GetAndFaultOutcome> getAndFaultObserver;
  private final OperationObserver<AuthoritativeTierOperationOutcomes.ComputeIfAbsentAndFaultOutcome> computeIfAbsentAndFaultObserver;
  private final OperationObserver<AuthoritativeTierOperationOutcomes.FlushOutcome> flushObserver;

  private final OperationObserver<LowerCachingTierOperationsOutcome.InvalidateOutcome> invalidateObserver;
  private final OperationObserver<LowerCachingTierOperationsOutcome.InvalidateAllOutcome> invalidateAllObserver;
  private final OperationObserver<LowerCachingTierOperationsOutcome.InvalidateAllWithHashOutcome> invalidateAllWithHashObserver;
  private final OperationObserver<LowerCachingTierOperationsOutcome.GetAndRemoveOutcome> getAndRemoveObserver;
  private final OperationObserver<LowerCachingTierOperationsOutcome.InstallMappingOutcome> installMappingObserver;

  protected final OffHeapStoreStatsSettings offHeapStoreStatsSettings;

  private volatile InvalidationValve valve;
  protected BackingMapEvictionListener<K, V> mapEvictionListener;
  private volatile CachingTier.InvalidationListener<K, V> invalidationListener = NULL_INVALIDATION_LISTENER;

  public AbstractOffHeapStore(String statisticsTag, Configuration<K, V> config, TimeSource timeSource, StoreEventDispatcher<K, V> eventDispatcher) {
    keyType = config.getKeyType();
    valueType = config.getValueType();
    expiry = config.getExpiry();

    this.timeSource = timeSource;
    this.eventDispatcher = eventDispatcher;

    this.offHeapStoreStatsSettings = new OffHeapStoreStatsSettings(this);
    StatisticsManager.associate(offHeapStoreStatsSettings).withParent(this);
    this.getObserver = operation(StoreOperationOutcomes.GetOutcome.class).of(this).named("get").tag(statisticsTag).build();
    this.putObserver = operation(StoreOperationOutcomes.PutOutcome.class).of(this).named("put").tag(statisticsTag).build();
    this.putIfAbsentObserver = operation(StoreOperationOutcomes.PutIfAbsentOutcome.class).of(this).named("putIfAbsent").tag(statisticsTag).build();
    this.removeObserver = operation(StoreOperationOutcomes.RemoveOutcome.class).of(this).named("remove").tag(statisticsTag).build();
    this.conditionalRemoveObserver = operation(StoreOperationOutcomes.ConditionalRemoveOutcome.class).of(this).named("conditionalRemove").tag(statisticsTag).build();
    this.replaceObserver = operation(StoreOperationOutcomes.ReplaceOutcome.class).of(this).named("replace").tag(statisticsTag).build();
    this.conditionalReplaceObserver = operation(StoreOperationOutcomes.ConditionalReplaceOutcome.class).of(this).named("conditionalReplace").tag(statisticsTag).build();
    this.computeObserver = operation(StoreOperationOutcomes.ComputeOutcome.class).of(this).named("compute").tag(statisticsTag).build();
    this.computeIfAbsentObserver = operation(StoreOperationOutcomes.ComputeIfAbsentOutcome.class).of(this).named("computeIfAbsent").tag(statisticsTag).build();
    this.evictionObserver = operation(StoreOperationOutcomes.EvictionOutcome.class).of(this).named("eviction").tag(statisticsTag).build();
    this.expirationObserver = operation(StoreOperationOutcomes.ExpirationOutcome.class).of(this).named("expiration").tag(statisticsTag).build();

    this.getAndFaultObserver = operation(AuthoritativeTierOperationOutcomes.GetAndFaultOutcome.class).of(this).named("getAndFault").tag(statisticsTag).build();
    this.computeIfAbsentAndFaultObserver = operation(AuthoritativeTierOperationOutcomes.ComputeIfAbsentAndFaultOutcome.class).of(this).named("computeIfAbsentAndFault").tag(statisticsTag).build();
    this.flushObserver = operation(AuthoritativeTierOperationOutcomes.FlushOutcome.class).of(this).named("flush").tag(statisticsTag).build();

    this.invalidateObserver = operation(LowerCachingTierOperationsOutcome.InvalidateOutcome.class).of(this).named("invalidate").tag(statisticsTag).build();
    this.invalidateAllObserver = operation(LowerCachingTierOperationsOutcome.InvalidateAllOutcome.class).of(this).named("invalidateAll").tag(statisticsTag).build();
    this.invalidateAllWithHashObserver = operation(LowerCachingTierOperationsOutcome.InvalidateAllWithHashOutcome.class).of(this).named("invalidateAllWithHash").tag(statisticsTag).build();
    this.getAndRemoveObserver= operation(LowerCachingTierOperationsOutcome.GetAndRemoveOutcome.class).of(this).named("getAndRemove").tag(statisticsTag).build();
    this.installMappingObserver= operation(LowerCachingTierOperationsOutcome.InstallMappingOutcome.class).of(this).named("installMapping").tag(statisticsTag).build();

    StatisticsManager.createPassThroughStatistic(this, "allocatedMemory", Collections.singleton(statisticsTag), new Callable<Number>() {
      @Override
      public Number call() throws Exception {
        return backingMap().allocatedMemory();
      }
    });
    StatisticsManager.createPassThroughStatistic(this, "occupiedMemory", Collections.singleton(statisticsTag), new Callable<Number>() {
      @Override
      public Number call() throws Exception {
        return backingMap().occupiedMemory();
      }
    });
    StatisticsManager.createPassThroughStatistic(this, "dataAllocatedMemory", Collections.singleton(statisticsTag), new Callable<Number>() {
      @Override
      public Number call() throws Exception {
        return backingMap().dataAllocatedMemory();
      }
    });
    StatisticsManager.createPassThroughStatistic(this, "dataOccupiedMemory", Collections.singleton(statisticsTag), new Callable<Number>() {
      @Override
      public Number call() throws Exception {
        return backingMap().dataOccupiedMemory();
      }
    });
    StatisticsManager.createPassThroughStatistic(this, "dataSize", Collections.singleton(statisticsTag), new Callable<Number>() {
      @Override
      public Number call() throws Exception {
        return backingMap().dataSize();
      }
    });
    StatisticsManager.createPassThroughStatistic(this, "dataVitalMemory", Collections.singleton(statisticsTag), new Callable<Number>() {
      @Override
      public Number call() throws Exception {
        return backingMap().dataVitalMemory();
      }
    });
    StatisticsManager.createPassThroughStatistic(this, "longSize", Collections.singleton(statisticsTag), new Callable<Number>() {
      @Override
      public Number call() throws Exception {
        return backingMap().longSize();
      }
    });
    StatisticsManager.createPassThroughStatistic(this, "vitalMemory", Collections.singleton(statisticsTag), new Callable<Number>() {
      @Override
      public Number call() throws Exception {
        return backingMap().vitalMemory();
      }
    });
    StatisticsManager.createPassThroughStatistic(this, "removedSlotCount", Collections.singleton(statisticsTag), new Callable<Number>() {
      @Override
      public Number call() throws Exception {
        return backingMap().removedSlotCount();
      }
    });
    StatisticsManager.createPassThroughStatistic(this, "reprobeLength", Collections.singleton(statisticsTag), new Callable<Number>() {
      @Override
      public Number call() throws Exception {
        return backingMap().reprobeLength();
      }
    });
    StatisticsManager.createPassThroughStatistic(this, "usedSlotCount", Collections.singleton(statisticsTag), new Callable<Number>() {
      @Override
      public Number call() throws Exception {
        return backingMap().usedSlotCount();
      }
    });
    StatisticsManager.createPassThroughStatistic(this, "tableCapacity", Collections.singleton(statisticsTag), new Callable<Number>() {
      @Override
      public Number call() throws Exception {
        return backingMap().tableCapacity();
      }
    });

    this.mapEvictionListener = new BackingMapEvictionListener<K, V>(eventDispatcher, evictionObserver);
  }

  @Override
  public Store.ValueHolder<V> get(K key) throws StoreAccessException {
    checkKey(key);
    getObserver.begin();
    ValueHolder<V> result = internalGet(key, true, true);
    if (result == null) {
      getObserver.end(StoreOperationOutcomes.GetOutcome.MISS);
    } else {
      getObserver.end(StoreOperationOutcomes.GetOutcome.HIT);
    }
    return result;
  }

  private Store.ValueHolder<V> internalGet(K key, final boolean updateAccess, final boolean touchValue) throws StoreAccessException {

    final StoreEventSink<K, V> eventSink = eventDispatcher.eventSink();
    final AtomicReference<OffHeapValueHolder<V>> heldValue = new AtomicReference<OffHeapValueHolder<V>>();
    try {
      OffHeapValueHolder<V> result = backingMap().computeIfPresent(key, new BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>>() {
        @Override
        public OffHeapValueHolder<V> apply(K mappedKey, OffHeapValueHolder<V> mappedValue) {
          long now = timeSource.getTimeMillis();

          if (mappedValue.isExpired(now, TimeUnit.MILLISECONDS)) {
            onExpiration(mappedKey, mappedValue, eventSink);
            return null;
          }

          if (updateAccess) {
            mappedValue.forceDeserialization();
            OffHeapValueHolder<V> valueHolder = setAccessTimeAndExpiryThenReturnMapping(mappedKey, mappedValue, now, eventSink);
            if (valueHolder == null) {
              heldValue.set(mappedValue);
            }
            return valueHolder;
          } else if (touchValue) {
            mappedValue.forceDeserialization();
          }
          return mappedValue;
        }
      });
      if (result == null && heldValue.get() != null) {
        result = heldValue.get();
      }
      eventDispatcher.releaseEventSink(eventSink);
      return result;
    } catch (RuntimeException re) {
      eventDispatcher.releaseEventSinkAfterFailure(eventSink, re);
      handleRuntimeException(re);
      return null;
    }
  }

  @Override
  public boolean containsKey(K key) throws StoreAccessException {
    checkKey(key);
    return internalGet(key, false, false) != null;
  }

  @Override
  public PutStatus put(final K key, final V value) throws StoreAccessException {
    putObserver.begin();
    checkKey(key);
    checkValue(value);

    final AtomicBoolean added = new AtomicBoolean();
    final AtomicReference<OffHeapValueHolder<V>> replacedVal = new AtomicReference<OffHeapValueHolder<V>>(null);
    final StoreEventSink<K, V> eventSink = eventDispatcher.eventSink();

    final long now = timeSource.getTimeMillis();
    try {
      BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>> mappingFunction = new BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>>() {
        @Override
        public OffHeapValueHolder<V> apply(K mappedKey, OffHeapValueHolder<V> mappedValue) {

          if (mappedValue != null && mappedValue.isExpired(now, TimeUnit.MILLISECONDS)) {
            mappedValue = null;
          }

          if (mappedValue == null) {
            OffHeapValueHolder<V> newValue = newCreateValueHolder(key, value, now, eventSink);
            added.set(newValue != null);
            return newValue;
          } else {
            OffHeapValueHolder<V> newValue = newUpdatedValueHolder(key, value, mappedValue, now, eventSink);
            replacedVal.set(mappedValue);
            return newValue;
          }
        }
      };
      computeWithRetry(key, mappingFunction, false);
      eventDispatcher.releaseEventSink(eventSink);
      if (replacedVal.get() != null) {
        putObserver.end(StoreOperationOutcomes.PutOutcome.REPLACED);
        return PutStatus.UPDATE;
      } else if (added.get()) {
        putObserver.end(StoreOperationOutcomes.PutOutcome.PUT);
        return PutStatus.PUT;
      } else {
        putObserver.end(StoreOperationOutcomes.PutOutcome.REPLACED);
        return PutStatus.NOOP;
      }
    } catch (StoreAccessException caex) {
      eventDispatcher.releaseEventSinkAfterFailure(eventSink, caex);
      throw caex;
    } catch (RuntimeException re) {
      eventDispatcher.releaseEventSinkAfterFailure(eventSink, re);
      throw re;
    }
  }

  @Override
  public Store.ValueHolder<V> putIfAbsent(final K key, final V value) throws NullPointerException, StoreAccessException {
    putIfAbsentObserver.begin();
    checkKey(key);
    checkValue(value);

    final AtomicReference<Store.ValueHolder<V>> returnValue = new AtomicReference<Store.ValueHolder<V>>();
    final StoreEventSink<K, V> eventSink = eventDispatcher.eventSink();

    try {
      BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>> mappingFunction = new BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>>() {
        @Override
        public OffHeapValueHolder<V> apply(K mappedKey, OffHeapValueHolder<V> mappedValue) {
          long now = timeSource.getTimeMillis();

          if (mappedValue == null || mappedValue.isExpired(now, TimeUnit.MILLISECONDS)) {
            if (mappedValue != null) {
              onExpiration(mappedKey, mappedValue, eventSink);
            }
            return newCreateValueHolder(mappedKey, value, now, eventSink);
          }
          mappedValue.forceDeserialization();
          returnValue.set(mappedValue);
          return setAccessTimeAndExpiryThenReturnMapping(mappedKey, mappedValue, now, eventSink);
        }
      };
      computeWithRetry(key, mappingFunction, false);

      eventDispatcher.releaseEventSink(eventSink);

      ValueHolder<V> resultHolder = returnValue.get();
      if (resultHolder == null) {
        putIfAbsentObserver.end(StoreOperationOutcomes.PutIfAbsentOutcome.PUT);
        return null;
      } else {
        putIfAbsentObserver.end(StoreOperationOutcomes.PutIfAbsentOutcome.HIT);
        return resultHolder;
      }
    } catch (StoreAccessException caex) {
      eventDispatcher.releaseEventSinkAfterFailure(eventSink, caex);
      throw caex;
    } catch (RuntimeException re) {
      eventDispatcher.releaseEventSinkAfterFailure(eventSink, re);
      throw re;
    }
  }

  @Override
  public boolean remove(final K key) throws StoreAccessException {
    removeObserver.begin();
    checkKey(key);

    final StoreEventSink<K, V> eventSink = eventDispatcher.eventSink();
    final long now = timeSource.getTimeMillis();

    final AtomicBoolean removed = new AtomicBoolean(false);
    try {

      backingMap().computeIfPresent(key, new BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>>() {
        @Override
        public OffHeapValueHolder<V> apply(K mappedKey, OffHeapValueHolder<V> mappedValue) {

          if (mappedValue != null && mappedValue.isExpired(now, TimeUnit.MILLISECONDS)) {
            onExpiration(mappedKey, mappedValue, eventSink);
            return null;
          }

          if (mappedValue != null) {
            removed.set(true);
            eventSink.removed(mappedKey, mappedValue);
          }
          return null;
        }
      });

      eventDispatcher.releaseEventSink(eventSink);

      if (removed.get()) {
        removeObserver.end(StoreOperationOutcomes.RemoveOutcome.REMOVED);
      } else {
        removeObserver.end(StoreOperationOutcomes.RemoveOutcome.MISS);
      }
      return removed.get();
    } catch (RuntimeException re) {
      eventDispatcher.releaseEventSinkAfterFailure(eventSink, re);
      handleRuntimeException(re);
      return false;
    }
  }

  @Override
  public RemoveStatus remove(final K key, final V value) throws StoreAccessException {
    conditionalRemoveObserver.begin();
    checkKey(key);
    checkValue(value);

    final AtomicBoolean removed = new AtomicBoolean(false);
    final StoreEventSink<K, V> eventSink = eventDispatcher.eventSink();
    final AtomicBoolean mappingExists = new AtomicBoolean();

    try {
      backingMap().computeIfPresent(key, new BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>>() {
        @Override
        public OffHeapValueHolder<V> apply(K mappedKey, OffHeapValueHolder<V> mappedValue) {
          long now = timeSource.getTimeMillis();

          if (mappedValue.isExpired(now, TimeUnit.MILLISECONDS)) {
            onExpiration(mappedKey, mappedValue, eventSink);
            return null;
          } else if (mappedValue.value().equals(value)) {
            removed.set(true);
            eventSink.removed(mappedKey, mappedValue);
            return null;
          } else {
            mappingExists.set(true);
            return setAccessTimeAndExpiryThenReturnMapping(mappedKey, mappedValue, now, eventSink);
          }
        }
      });

      eventDispatcher.releaseEventSink(eventSink);

      if (removed.get()) {
        conditionalRemoveObserver.end(StoreOperationOutcomes.ConditionalRemoveOutcome.REMOVED);
        return RemoveStatus.REMOVED;
      } else {
        conditionalRemoveObserver.end(StoreOperationOutcomes.ConditionalRemoveOutcome.MISS);
        if (mappingExists.get()) {
          return RemoveStatus.KEY_PRESENT;
        } else {
          return RemoveStatus.KEY_MISSING;
        }
      }
    } catch (RuntimeException re) {
      eventDispatcher.releaseEventSinkAfterFailure(eventSink, re);
      handleRuntimeException(re);
      // To please the compiler, the above WILL throw
      return RemoveStatus.KEY_MISSING;
    }

  }

  @Override
  public ValueHolder<V> replace(final K key, final V value) throws NullPointerException, StoreAccessException {
    replaceObserver.begin();
    checkKey(key);
    checkValue(value);

    final AtomicReference<Store.ValueHolder<V>> returnValue = new AtomicReference<Store.ValueHolder<V>>(null);
    final StoreEventSink<K, V> eventSink = eventDispatcher.eventSink();
    BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>> mappingFunction = new BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>>() {
      @Override
      public OffHeapValueHolder<V> apply(K mappedKey, OffHeapValueHolder<V> mappedValue) {
        long now = timeSource.getTimeMillis();

        if (mappedValue == null || mappedValue.isExpired(now, TimeUnit.MILLISECONDS)) {
          if (mappedValue != null) {
            onExpiration(mappedKey, mappedValue, eventSink);
          }
          return null;
        } else {
          returnValue.set(mappedValue);
          return newUpdatedValueHolder(mappedKey, value, mappedValue, now, eventSink);
        }
      }
    };
    try {
      computeWithRetry(key, mappingFunction, false);
      eventDispatcher.releaseEventSink(eventSink);
      ValueHolder<V> resultHolder = returnValue.get();
      if (resultHolder != null) {
        replaceObserver.end(StoreOperationOutcomes.ReplaceOutcome.REPLACED);
      } else {
        replaceObserver.end(StoreOperationOutcomes.ReplaceOutcome.MISS);
      }
      return resultHolder;
    } catch (StoreAccessException caex) {
      eventDispatcher.releaseEventSinkAfterFailure(eventSink, caex);
      throw caex;
    } catch (RuntimeException re) {
      eventDispatcher.releaseEventSinkAfterFailure(eventSink, re);
      throw re;
    }
  }

  @Override
  public ReplaceStatus replace(final K key, final V oldValue, final V newValue) throws NullPointerException, IllegalArgumentException, StoreAccessException {
    conditionalReplaceObserver.begin();
    checkKey(key);
    checkValue(oldValue);
    checkValue(newValue);

    final AtomicBoolean replaced = new AtomicBoolean(false);
    final StoreEventSink<K, V> eventSink = eventDispatcher.eventSink();
    final AtomicBoolean mappingExists = new AtomicBoolean();

    BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>> mappingFunction = new BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>>() {
      @Override
      public OffHeapValueHolder<V> apply(K mappedKey, OffHeapValueHolder<V> mappedValue) {
        long now = timeSource.getTimeMillis();

        if (mappedValue == null || mappedValue.isExpired(now, TimeUnit.MILLISECONDS)) {
          if (mappedValue != null) {
            onExpiration(mappedKey, mappedValue, eventSink);
          }
          return null;
        } else if (oldValue.equals(mappedValue.value())) {
          replaced.set(true);
          return newUpdatedValueHolder(mappedKey, newValue, mappedValue, now, eventSink);
        } else {
          mappingExists.set(true);
          return setAccessTimeAndExpiryThenReturnMapping(mappedKey, mappedValue, now, eventSink);
        }
      }
    };

    try {
      computeWithRetry(key, mappingFunction, false);
      eventDispatcher.releaseEventSink(eventSink);
      if (replaced.get()) {
        conditionalReplaceObserver.end(StoreOperationOutcomes.ConditionalReplaceOutcome.REPLACED);
        return ReplaceStatus.HIT;
      } else {
        conditionalReplaceObserver.end(StoreOperationOutcomes.ConditionalReplaceOutcome.MISS);
        if (mappingExists.get()) {
          return ReplaceStatus.MISS_PRESENT;
        } else {
          return ReplaceStatus.MISS_NOT_PRESENT;
        }
      }
    } catch (StoreAccessException caex) {
      eventDispatcher.releaseEventSinkAfterFailure(eventSink, caex);
      throw caex;
    } catch (RuntimeException re) {
      eventDispatcher.releaseEventSinkAfterFailure(eventSink, re);
      throw re;
    }
  }

  @Override
  public void clear() throws StoreAccessException {
    try {
      backingMap().clear();
    } catch (RuntimeException re) {
      handleRuntimeException(re);
    }
  }

  @Override
  public StoreEventSource<K, V> getStoreEventSource() {
    return eventDispatcher;
  }

  @Override
  public Iterator<Cache.Entry<K, ValueHolder<V>>> iterator() {
    return new Iterator<Cache.Entry<K, ValueHolder<V>>>() {
      private final java.util.Iterator<Map.Entry<K, OffHeapValueHolder<V>>> mapIterator = backingMap().entrySet().iterator();

      @Override
      public boolean hasNext() {
        return mapIterator.hasNext();
      }

      @Override
      public Cache.Entry<K, ValueHolder<V>> next() throws StoreAccessException {
        Map.Entry<K, OffHeapValueHolder<V>> next = mapIterator.next();
        final K key = next.getKey();
        final OffHeapValueHolder<V> value = next.getValue();
        return new Cache.Entry<K, ValueHolder<V>>() {
          @Override
          public K getKey() {
            return key;
          }
          @Override
          public ValueHolder<V> getValue() {
            return value;
          }
        };
      }
    };
  }

  @Override
  public ValueHolder<V> compute(K key, BiFunction<? super K, ? super V, ? extends V> mappingFunction) throws StoreAccessException {
    return compute(key, mappingFunction, REPLACE_EQUALS_TRUE);
  }

  @Override
  public ValueHolder<V> compute(final K key, final BiFunction<? super K, ? super V, ? extends V> mappingFunction, final NullaryFunction<Boolean> replaceEqual) throws StoreAccessException {
    computeObserver.begin();
    checkKey(key);

    final AtomicBoolean write = new AtomicBoolean(false);
    final AtomicReference<OffHeapValueHolder<V>> valueHeld = new AtomicReference<OffHeapValueHolder<V>>();
    final StoreEventSink<K, V> eventSink = eventDispatcher.eventSink();
    BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>> computeFunction = new BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>>() {
      @Override
      public OffHeapValueHolder<V> apply(K mappedKey, OffHeapValueHolder<V> mappedValue) {
        long now = timeSource.getTimeMillis();
        V existingValue = null;
        if (mappedValue == null || mappedValue.isExpired(now, TimeUnit.MILLISECONDS)) {
          if (mappedValue != null) {
            onExpiration(mappedKey, mappedValue, eventSink);
          }
          mappedValue = null;
        } else {
          existingValue = mappedValue.value();
        }
        V computedValue = mappingFunction.apply(mappedKey, existingValue);
        if (computedValue == null) {
          if (mappedValue != null) {
            write.set(true);
            eventSink.removed(mappedKey, mappedValue);
          }
          return null;
        } else if (safeEquals(existingValue, computedValue) && !replaceEqual.apply()) {
          if (mappedValue != null) {
            OffHeapValueHolder<V> valueHolder = setAccessTimeAndExpiryThenReturnMapping(mappedKey, mappedValue, now, eventSink);
            if (valueHolder == null) {
              valueHeld.set(mappedValue);
            }
            return valueHolder;
          } else {
            return null;
          }
        }

        checkValue(computedValue);
        write.set(true);
        if (mappedValue != null) {
          OffHeapValueHolder<V> valueHolder = newUpdatedValueHolder(key, computedValue, mappedValue, now, eventSink);
          if (valueHolder == null) {
            valueHeld.set(new BasicOffHeapValueHolder<V>(mappedValue.getId(), computedValue, now, now));
          }
          return valueHolder;
        } else {
          return newCreateValueHolder(key, computedValue, now, eventSink);
        }
      }
    };

    OffHeapValueHolder<V> result;
    try {
      result = computeWithRetry(key, computeFunction, false);
      if (result == null && valueHeld.get() != null) {
        result = valueHeld.get();
      }
      eventDispatcher.releaseEventSink(eventSink);
      if (result == null) {
        if (write.get()) {
          computeObserver.end(StoreOperationOutcomes.ComputeOutcome.REMOVED);
        } else {
          computeObserver.end(StoreOperationOutcomes.ComputeOutcome.MISS);
        }
      } else if (write.get()) {
        computeObserver.end(StoreOperationOutcomes.ComputeOutcome.PUT);
      } else {
        computeObserver.end(StoreOperationOutcomes.ComputeOutcome.HIT);
      }
      return result;
    } catch (StoreAccessException caex) {
      eventDispatcher.releaseEventSinkAfterFailure(eventSink, caex);
      throw caex;
    } catch (RuntimeException re) {
      eventDispatcher.releaseEventSinkAfterFailure(eventSink, re);
      throw re;
    }
  }

  @Override
  public ValueHolder<V> computeIfAbsent(final K key, final Function<? super K, ? extends V> mappingFunction) throws StoreAccessException {
    return internalComputeIfAbsent(key, mappingFunction, false, false);
  }

  private Store.ValueHolder<V> internalComputeIfAbsent(final K key, final Function<? super K, ? extends V> mappingFunction, boolean fault, final boolean delayedDeserialization) throws StoreAccessException {
    if (fault) {
      computeIfAbsentAndFaultObserver.begin();
    } else {
      computeIfAbsentObserver.begin();
    }
    checkKey(key);

    final AtomicBoolean write = new AtomicBoolean(false);
    final AtomicReference<OffHeapValueHolder<V>> valueHeld = new AtomicReference<OffHeapValueHolder<V>>();
    final StoreEventSink<K, V> eventSink = eventDispatcher.eventSink();
    BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>> computeFunction = new BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>>() {
      @Override
      public OffHeapValueHolder<V> apply(K mappedKey, OffHeapValueHolder<V> mappedValue) {
        long now = timeSource.getTimeMillis();
        if (mappedValue == null || mappedValue.isExpired(now, TimeUnit.MILLISECONDS)) {
          if (mappedValue != null) {
            onExpiration(mappedKey, mappedValue, eventSink);
          }
          write.set(true);
          V computedValue = mappingFunction.apply(mappedKey);
          if (computedValue == null) {
            return null;
          } else {
            checkValue(computedValue);
            return newCreateValueHolder(mappedKey, computedValue, now, eventSink);
          }
        } else {
          OffHeapValueHolder<V> valueHolder = setAccessTimeAndExpiryThenReturnMapping(mappedKey, mappedValue, now, eventSink);
          if (valueHolder != null) {
            if (delayedDeserialization) {
              mappedValue.detach();
            } else {
              mappedValue.forceDeserialization();
            }
          } else {
            valueHeld.set(mappedValue);
          }
          return valueHolder;
        }
      }
    };

    OffHeapValueHolder<V> computeResult;
    try {
      computeResult = computeWithRetry(key, computeFunction, fault);
      if (computeResult == null && valueHeld.get() != null) {
        computeResult = valueHeld.get();
      }
      eventDispatcher.releaseEventSink(eventSink);
      if (write.get()) {
        if (computeResult != null) {
          if (fault) {
            computeIfAbsentAndFaultObserver.end(AuthoritativeTierOperationOutcomes.ComputeIfAbsentAndFaultOutcome.PUT);
          } else {
            computeIfAbsentObserver.end(StoreOperationOutcomes.ComputeIfAbsentOutcome.PUT);
          }
        } else {
          if (fault) {
            computeIfAbsentAndFaultObserver.end(AuthoritativeTierOperationOutcomes.ComputeIfAbsentAndFaultOutcome.NOOP);
          } else {
            computeIfAbsentObserver.end(StoreOperationOutcomes.ComputeIfAbsentOutcome.NOOP);
          }
        }
      } else {
        if (fault) {
          computeIfAbsentAndFaultObserver.end(AuthoritativeTierOperationOutcomes.ComputeIfAbsentAndFaultOutcome.HIT);
        } else {
          computeIfAbsentObserver.end(StoreOperationOutcomes.ComputeIfAbsentOutcome.HIT);
        }
      }
      return computeResult;
    } catch (StoreAccessException caex) {
      eventDispatcher.releaseEventSinkAfterFailure(eventSink, caex);
      throw caex;
    } catch (RuntimeException re) {
      eventDispatcher.releaseEventSinkAfterFailure(eventSink, re);
      throw re;
    }
  }

  @Override
  public Map<K, ValueHolder<V>> bulkCompute(Set<? extends K> keys, Function<Iterable<? extends Map.Entry<? extends K, ? extends V>>, Iterable<? extends Map.Entry<? extends K, ? extends V>>> remappingFunction) throws StoreAccessException {
    return bulkCompute(keys, remappingFunction, REPLACE_EQUALS_TRUE);
  }

  @Override
  public Map<K, ValueHolder<V>> bulkCompute(Set<? extends K> keys, final Function<Iterable<? extends Map.Entry<? extends K, ? extends V>>, Iterable<? extends Map.Entry<? extends K, ? extends V>>> remappingFunction, NullaryFunction<Boolean> replaceEqual) throws StoreAccessException {
    Map<K, ValueHolder<V>> result = new HashMap<K, ValueHolder<V>>();
    for (K key : keys) {
      checkKey(key);
      BiFunction<K, V, V> biFunction = new BiFunction<K, V, V>() {
        @Override
        public V apply(final K k, final V v) {
          Map.Entry<K, V> entry = new Map.Entry<K, V>() {
            @Override
            public K getKey() {
              return k;
            }

            @Override
            public V getValue() {
              return v;
            }

            @Override
            public V setValue(V value) {
              throw new UnsupportedOperationException();
            }
          };
          java.util.Iterator<? extends Map.Entry<? extends K, ? extends V>> iterator = remappingFunction.apply(Collections
              .singleton(entry)).iterator();
          Map.Entry<? extends K, ? extends V> result = iterator.next();
          if (result != null) {
            checkKey(result.getKey());
            return result.getValue();
          } else {
            return null;
          }
        }
      };
      ValueHolder<V> computed = compute(key, biFunction, replaceEqual);
      result.put(key, computed);
    }
    return result;
  }

  @Override
  public Map<K, ValueHolder<V>> bulkComputeIfAbsent(Set<? extends K> keys, final Function<Iterable<? extends K>, Iterable<? extends Map.Entry<? extends K, ? extends V>>> mappingFunction) throws StoreAccessException {
    Map<K, ValueHolder<V>> result = new HashMap<K, ValueHolder<V>>();
    for (K key : keys) {
      checkKey(key);
      Function<K, V> function = new Function<K, V>() {
        @Override
        public V apply(K k) {
          java.util.Iterator<? extends Map.Entry<? extends K, ? extends V>> iterator = mappingFunction.apply(Collections.singleton(k)).iterator();
          Map.Entry<? extends K, ? extends V> result = iterator.next();
          if (result != null) {
            checkKey(result.getKey());
            return result.getValue();
          } else {
            return null;
          }
        }
      };
      ValueHolder<V> computed = computeIfAbsent(key, function);
      result.put(key, computed);
    }
    return result;
  }

  @Override
  public ValueHolder<V> getAndFault(K key) throws StoreAccessException {
    getAndFaultObserver.begin();
    checkKey(key);
    ValueHolder<V> mappedValue = null;
    final StoreEventSink<K, V> eventSink = eventDispatcher.eventSink();
    try {
      mappedValue = backingMap().computeIfPresentAndPin(key, new BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>>() {
        @Override
        public OffHeapValueHolder<V> apply(K mappedKey, OffHeapValueHolder<V> mappedValue) {
          if(mappedValue.isExpired(timeSource.getTimeMillis(), TimeUnit.MILLISECONDS)) {
            onExpiration(mappedKey, mappedValue, eventSink);
            return null;
          }
          mappedValue.detach();
          return mappedValue;
        }
      });

      eventDispatcher.releaseEventSink(eventSink);

      if (mappedValue == null) {
        getAndFaultObserver.end(AuthoritativeTierOperationOutcomes.GetAndFaultOutcome.MISS);
      } else {
        getAndFaultObserver.end(AuthoritativeTierOperationOutcomes.GetAndFaultOutcome.HIT);
      }
    } catch (RuntimeException re) {
      eventDispatcher.releaseEventSinkAfterFailure(eventSink, re);
      handleRuntimeException(re);
    }
    return mappedValue;
  }

  @Override
  public ValueHolder<V> computeIfAbsentAndFault(K key, Function<? super K, ? extends V> mappingFunction) throws StoreAccessException {
    return internalComputeIfAbsent(key, mappingFunction, true, true);
  }

  @Override
  public boolean flush(K key, final ValueHolder<V> valueFlushed) {
    flushObserver.begin();
    checkKey(key);
    final StoreEventSink<K, V> eventSink = eventDispatcher.eventSink();

    try {
      boolean result = backingMap().computeIfPinned(key, new BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>>() {
        @Override
        public OffHeapValueHolder<V> apply(K k, OffHeapValueHolder<V> valuePresent) {
          if (valuePresent.getId() == valueFlushed.getId()) {
            if (valueFlushed.isExpired(timeSource.getTimeMillis(), TimeUnit.MILLISECONDS)) {
              onExpiration(k, valuePresent, eventSink);
              return null;
            }
            valuePresent.updateMetadata(valueFlushed);
            valuePresent.writeBack();
          }
          return valuePresent;
        }
      }, new Function<OffHeapValueHolder<V>, Boolean>() {
        @Override
        public Boolean apply(OffHeapValueHolder<V> valuePresent) {
          return valuePresent.getId() == valueFlushed.getId();
        }
      });
      eventDispatcher.releaseEventSink(eventSink);
      if (result) {
        flushObserver.end(AuthoritativeTierOperationOutcomes.FlushOutcome.HIT);
        return true;
      } else {
        flushObserver.end(AuthoritativeTierOperationOutcomes.FlushOutcome.MISS);
        return false;
      }
    } catch (RuntimeException re) {
      eventDispatcher.releaseEventSinkAfterFailure(eventSink, re);
      throw re;
    }
  }

  @Override
  public void setInvalidationValve(InvalidationValve valve) {
    this.valve = valve;
  }

  @Override
  public void setInvalidationListener(CachingTier.InvalidationListener<K, V> invalidationListener) {
    this.invalidationListener = invalidationListener;
    mapEvictionListener.setInvalidationListener(invalidationListener);
  }

  @Override
  public void invalidate(final K key) throws StoreAccessException {
    invalidateObserver.begin();
    final AtomicBoolean removed = new AtomicBoolean(false);
    try {
      backingMap().computeIfPresent(key, new BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>>() {
        @Override
        public OffHeapValueHolder<V> apply(final K k, final OffHeapValueHolder<V> present) {
          removed.set(true);
          notifyInvalidation(key, present);
          return null;
        }
      });
      if (removed.get()) {
        invalidateObserver.end(LowerCachingTierOperationsOutcome.InvalidateOutcome.REMOVED);
      } else {
        invalidateObserver.end(LowerCachingTierOperationsOutcome.InvalidateOutcome.MISS);
      }
    } catch (RuntimeException re) {
      handleRuntimeException(re);
    }
  }

  @Override
  public void invalidateAll() throws StoreAccessException {
    invalidateAllObserver.begin();
    StoreAccessException exception = null;
    long errorCount = 0;
    for (K k : backingMap().keySet()) {
      try {
        invalidate(k);
      } catch (StoreAccessException e) {
        errorCount++;
        if (exception == null) {
          exception = e;
        }
      }
    }
    if (exception != null) {
      invalidateAllObserver.end(LowerCachingTierOperationsOutcome.InvalidateAllOutcome.FAILURE);
      throw new StoreAccessException("invalidateAll failed - error count: " + errorCount, exception);
    }
    invalidateAllObserver.end(LowerCachingTierOperationsOutcome.InvalidateAllOutcome.SUCCESS);
  }

  @Override
  public void invalidateAllWithHash(long hash) {
    invalidateAllWithHashObserver.begin();
    Map<K, OffHeapValueHolder<V>> removed = backingMap().removeAllWithHash((int) hash);
    for (Map.Entry<K, OffHeapValueHolder<V>> entry : removed.entrySet()) {
      notifyInvalidation(entry.getKey(), entry.getValue());
    }
    invalidateAllWithHashObserver.end(LowerCachingTierOperationsOutcome.InvalidateAllWithHashOutcome.SUCCESS);
  }

  private void notifyInvalidation(final K key, final ValueHolder<V> p) {
    final CachingTier.InvalidationListener<K, V> invalidationListener = this.invalidationListener;
    if (invalidationListener != null) {
      invalidationListener.onInvalidation(key, p);
    }
  }

  /**
   * {@inheritDoc}
   * Note that this implementation is atomic.
   */
  @Override
  public ValueHolder<V> getAndRemove(final K key) throws StoreAccessException {
    getAndRemoveObserver.begin();
    checkKey(key);

    final AtomicReference<ValueHolder<V>> valueHolderAtomicReference = new AtomicReference<ValueHolder<V>>();
    BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>> computeFunction = new BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>>() {
      @Override
      public OffHeapValueHolder<V> apply(K mappedKey, OffHeapValueHolder<V> mappedValue) {
        long now = timeSource.getTimeMillis();
        if (mappedValue == null || mappedValue.isExpired(now, TimeUnit.MILLISECONDS)) {
          if (mappedValue != null) {
            onExpirationInCachingTier(mappedValue, key);
          }
          return null;
        }
        mappedValue.detach();
        valueHolderAtomicReference.set(mappedValue);
        return null;
      }
    };

    try {
      backingMap().compute(key, computeFunction, false);
      ValueHolder<V> result = valueHolderAtomicReference.get();
      if (result == null) {
        getAndRemoveObserver.end(LowerCachingTierOperationsOutcome.GetAndRemoveOutcome.MISS);
      } else {
        getAndRemoveObserver.end(LowerCachingTierOperationsOutcome.GetAndRemoveOutcome.HIT_REMOVED);
      }
      return result;
    } catch (RuntimeException re) {
      handleRuntimeException(re);
      return null;
    }
  }

  @Override
  public ValueHolder<V> installMapping(final K key, final Function<K, ValueHolder<V>> source) throws StoreAccessException {
    installMappingObserver.begin();
    BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>> computeFunction = new BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>>() {
      @Override
      public OffHeapValueHolder<V> apply(K k, OffHeapValueHolder<V> offHeapValueHolder) {
        if (offHeapValueHolder != null) {
          throw new AssertionError();
        }
        ValueHolder<V> valueHolder = source.apply(k);
        if (valueHolder != null) {
          if (valueHolder.isExpired(timeSource.getTimeMillis(), TimeUnit.MILLISECONDS)) {
            onExpirationInCachingTier(valueHolder, key);
            return null;
          } else {
            return newTransferValueHolder(valueHolder);
          }
        }
        return null;
      }
    };
    OffHeapValueHolder<V> computeResult;
    try {
      computeResult = computeWithRetry(key, computeFunction, false);
      if (computeResult != null) {
        installMappingObserver.end(LowerCachingTierOperationsOutcome.InstallMappingOutcome.PUT);
      } else {
        installMappingObserver.end(LowerCachingTierOperationsOutcome.InstallMappingOutcome.NOOP);
      }
      return computeResult;
    } catch (RuntimeException re) {
      handleRuntimeException(re);
      return null;
    }
  }

  private OffHeapValueHolder<V> computeWithRetry(K key, BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>> computeFunction, boolean fault) throws StoreAccessException {
    OffHeapValueHolder<V> computeResult = null;
    try {
      computeResult = backingMap().compute(key, computeFunction, fault);
    } catch (OversizeMappingException ex) {
      try {
        evictionAdvisor().setSwitchedOn(false);
        invokeValve();
        computeResult = backingMap().compute(key, computeFunction, fault);
      } catch (OversizeMappingException e) {
        throw new StoreAccessException("The element with key '" + key + "' is too large to be stored"
                                       + " in this offheap store.", e);
      } catch (RuntimeException e) {
        handleRuntimeException(e);
      } finally {
        evictionAdvisor().setSwitchedOn(true);
      }
    } catch (RuntimeException re) {
      handleRuntimeException(re);
    }
    return computeResult;
  }

  private boolean safeEquals(V existingValue, V computedValue) {
    return existingValue == computedValue || (existingValue != null && existingValue.equals(computedValue));
  }

  private static final NullaryFunction<Boolean> REPLACE_EQUALS_TRUE = new NullaryFunction<Boolean>() {
    @Override
    public Boolean apply() {
      return Boolean.TRUE;
    }
  };

  private OffHeapValueHolder<V> setAccessTimeAndExpiryThenReturnMapping(K key, OffHeapValueHolder<V> valueHolder, long now, StoreEventSink<K, V> eventSink) {
    Duration duration = Duration.ZERO;
    try {
      duration = expiry.getExpiryForAccess(key, valueHolder);
    } catch (RuntimeException re) {
      LOG.error("Expiry computation caused an exception - Expiry duration will be 0 ", re);
    }
    if (Duration.ZERO.equals(duration)) {
      onExpiration(key, valueHolder, eventSink);
      return null;
    }
    valueHolder.accessed(now, duration);
    valueHolder.writeBack();
    return valueHolder;
  }

  private OffHeapValueHolder<V> newUpdatedValueHolder(K key, V value, OffHeapValueHolder<V> existing, long now, StoreEventSink<K, V> eventSink) {
    eventSink.updated(key, existing, value);
    Duration duration = Duration.ZERO;
    try {
      duration = expiry.getExpiryForUpdate(key, existing, value);
    } catch (RuntimeException re) {
      LOG.error("Expiry computation caused an exception - Expiry duration will be 0 ", re);
    }
    if (Duration.ZERO.equals(duration)) {
      eventSink.expired(key, supplierOf(value));
      return null;
    }

    if (duration == null) {
      return new BasicOffHeapValueHolder<V>(backingMap().nextIdFor(key), value, now, existing.expirationTime(OffHeapValueHolder.TIME_UNIT));
    } else if (duration.isInfinite()) {
      return new BasicOffHeapValueHolder<V>(backingMap().nextIdFor(key), value, now, OffHeapValueHolder.NO_EXPIRE);
    } else {
      return new BasicOffHeapValueHolder<V>(backingMap().nextIdFor(key), value, now, safeExpireTime(now, duration));
    }
  }

  private OffHeapValueHolder<V> newCreateValueHolder(K key, V value, long now, StoreEventSink<K, V> eventSink) {
    Duration duration = Duration.ZERO;
    try {
      duration = expiry.getExpiryForCreation(key, value);
    } catch (RuntimeException re) {
      LOG.error("Expiry computation caused an exception - Expiry duration will be 0 ", re);
    }
    if (Duration.ZERO.equals(duration)) {
      return null;
    }

    eventSink.created(key, value);

    if (duration.isInfinite()) {
      return new BasicOffHeapValueHolder<V>(backingMap().nextIdFor(key), value, now, OffHeapValueHolder.NO_EXPIRE);
    } else {
      return new BasicOffHeapValueHolder<V>(backingMap().nextIdFor(key), value, now, safeExpireTime(now, duration));
    }
  }

  private OffHeapValueHolder<V> newTransferValueHolder(ValueHolder<V> valueHolder) {
    if (valueHolder instanceof BinaryValueHolder && ((BinaryValueHolder) valueHolder).isBinaryValueAvailable()) {
      return new BinaryOffHeapValueHolder<V>(valueHolder.getId(), valueHolder.value(), ((BinaryValueHolder)valueHolder).getBinaryValue(),
          valueHolder.creationTime(OffHeapValueHolder.TIME_UNIT), valueHolder.expirationTime(OffHeapValueHolder.TIME_UNIT),
          valueHolder.lastAccessTime(OffHeapValueHolder.TIME_UNIT), valueHolder.hits());
    } else {
      return new BasicOffHeapValueHolder<V>(valueHolder.getId(), valueHolder.value(), valueHolder.creationTime(OffHeapValueHolder.TIME_UNIT),
          valueHolder.expirationTime(OffHeapValueHolder.TIME_UNIT), valueHolder.lastAccessTime(OffHeapValueHolder.TIME_UNIT), valueHolder
          .hits());
    }
  }

  private void invokeValve() throws StoreAccessException {
    InvalidationValve valve = this.valve;
    if (valve != null) {
      valve.invalidateAll();
    }
  }

  private static long safeExpireTime(long now, Duration duration) {
    long millis = OffHeapValueHolder.TIME_UNIT.convert(duration.getLength(), duration.getTimeUnit());

    if (millis == Long.MAX_VALUE) {
      return Long.MAX_VALUE;
    }

    long result = now + millis;
    if (result < 0) {
      return Long.MAX_VALUE;
    }
    return result;
  }

  private void checkKey(K keyObject) {
    if (keyObject == null) {
      throw new NullPointerException();
    }
    if (!keyType.isAssignableFrom(keyObject.getClass())) {
      throw new ClassCastException("Invalid key type, expected : " + keyType.getName() + " but was : " + keyObject.getClass().getName());
    }
  }

  private void checkValue(V valueObject) {
    if (valueObject == null) {
      throw new NullPointerException();
    }
    if (!valueType.isAssignableFrom(valueObject.getClass())) {
      throw new ClassCastException("Invalid value type, expected : " + valueType.getName() + " but was : " + valueObject.getClass().getName());
    }
  }

  private void onExpirationInCachingTier(ValueHolder<V> mappedValue, K key) {
    expirationObserver.begin();
    invalidationListener.onInvalidation(key, mappedValue);
    expirationObserver.end(StoreOperationOutcomes.ExpirationOutcome.SUCCESS);
  }

  private void onExpiration(K mappedKey, ValueHolder<V> mappedValue, StoreEventSink<K, V> eventSink) {
    expirationObserver.begin();
    eventSink.expired(mappedKey, mappedValue);
    invalidationListener.onInvalidation(mappedKey, mappedValue);
    expirationObserver.end(StoreOperationOutcomes.ExpirationOutcome.SUCCESS);
  }

  protected abstract EhcacheOffHeapBackingMap<K, OffHeapValueHolder<V>> backingMap();

  protected abstract SwitchableEvictionAdvisor<K, OffHeapValueHolder<V>> evictionAdvisor();

  protected static <K, V> SwitchableEvictionAdvisor<K, OffHeapValueHolder<V>> wrap(EvictionAdvisor<? super K, ? super V> delegate) {
    return new OffHeapEvictionAdvisorWrapper<K, V>(delegate);
  }

  private static class OffHeapEvictionAdvisorWrapper<K, V> implements SwitchableEvictionAdvisor<K, OffHeapValueHolder<V>> {

    private final EvictionAdvisor<? super K, ? super V> delegate;
    private volatile boolean adviceEnabled;

    private OffHeapEvictionAdvisorWrapper(EvictionAdvisor<? super K, ? super V> delegate) {
      this.delegate = delegate;
    }

    @Override
    public boolean adviseAgainstEviction(K key, OffHeapValueHolder<V> value) {
      try {
        return delegate.adviseAgainstEviction(key, value.value());
      } catch (Exception e) {
        LOG.error("Exception raised while running eviction advisor " +
                  "- Eviction will assume entry is NOT advised against eviction", e);
        return false;
      }
    }

    @Override
    public boolean isSwitchedOn() {
      return adviceEnabled;
    }

    @Override
    public void setSwitchedOn(boolean switchedOn) {
      this.adviceEnabled = switchedOn;
    }
  }

  static class BackingMapEvictionListener<K, V> implements EhcacheSegmentFactory.EhcacheSegment.EvictionListener<K, OffHeapValueHolder<V>> {

    private final StoreEventDispatcher<K, V> eventDispatcher;
    private final OperationObserver<StoreOperationOutcomes.EvictionOutcome> evictionObserver;
    private volatile CachingTier.InvalidationListener<K, V> invalidationListener;

    private BackingMapEvictionListener(StoreEventDispatcher<K, V> eventDispatcher, OperationObserver<StoreOperationOutcomes.EvictionOutcome> evictionObserver) {
      this.eventDispatcher = eventDispatcher;
      this.evictionObserver = evictionObserver;
      this.invalidationListener = NULL_INVALIDATION_LISTENER;
    }

    public void setInvalidationListener(CachingTier.InvalidationListener<K, V> invalidationListener) {
      if (invalidationListener == null) {
        throw new NullPointerException("invalidation listener cannot be null");
      }
      this.invalidationListener = invalidationListener;
    }

    @Override
    public void onEviction(K key, OffHeapValueHolder<V> value) {
      evictionObserver.begin();
      StoreEventSink<K, V> eventSink = eventDispatcher.eventSink();
      try {
        eventSink.evicted(key, value);
        eventDispatcher.releaseEventSink(eventSink);
      } catch (RuntimeException re) {
        eventDispatcher.releaseEventSinkAfterFailure(eventSink, re);
      }
      invalidationListener.onInvalidation(key, value);
      evictionObserver.end(StoreOperationOutcomes.EvictionOutcome.SUCCESS);
    }
  }

  private static final class OffHeapStoreStatsSettings {
    @ContextAttribute("tags") private final Set<String> tags = new HashSet<String>(Arrays.asList("store"));
    @ContextAttribute("authoritativeTier") private final AbstractOffHeapStore<?, ?> authoritativeTier;

    OffHeapStoreStatsSettings(AbstractOffHeapStore<?, ?> store) {
      this.authoritativeTier = store;
    }
  }
}


text:
package edu.uri.egr.hermessample.samples;

import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.graphics.drawable.VectorDrawable;
import android.os.Bundle;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.widget.ImageView;
import android.widget.TextView;

import java.nio.ByteBuffer;

import butterknife.Bind;
import butterknife.BindColor;
import butterknife.ButterKnife;
import edu.uri.egr.hermesble.HermesBLE;
import edu.uri.egr.hermesble.attributes.BLStandardAttributes;
import edu.uri.egr.hermesble.evaluator.HeartRateEvaluator;
import edu.uri.egr.hermesble.ui.BLESelectionDialog;
import edu.uri.egr.hermessample.R;
import edu.uri.egr.hermesui.activity.HermesActivity;
import rx.Subscription;
import rx.functions.Action1;
import timber.log.Timber;

public class HeartRateActivity extends HermesActivity {

    // We need to bind our views so we can access them.
    @Bind(R.id.toolbar) Toolbar mToolbar;
    @Bind(R.id.heart) ImageView mHeart;
    @Bind(R.id.heart_rate) TextView mRate;

    @BindColor(R.color.red) int COLOR_HEART;

    // Create Activity global variables for things we need across different methods.
    private Subscription mDeviceSubscription;
    private BluetoothGatt mGatt;

    /*
    This is called when the Activity is created.  In Android, this will be when the activity is started fresh
    for the first time, or when the screen is rotated.  Pressing the back button will cause the view to be
    destroyed, but pressing home, and then using multitasking to get back, will not (most of the time)
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState); // Call super, we must do this because it handles a lot of nice things for us.
        setContentView(R.layout.activity_heartrate); // Set our content view for what we want to show on screen.
        setSupportActionBar(mToolbar); // Set our toolbar to the one we designated in the layout.

        // Create a new device selection dialog.
        BLESelectionDialog dialog = new BLESelectionDialog();

        // Now, we need to subscribe to it.  This might look like black magic, but just follow the comments.
        mDeviceSubscription = dialog.getObservable() // Get the Observable from the device dialog.

                // We then want to "map" this observable to a different one.
                // HermesBLE.connectAndListen outputs a different observable.  So, once we get to this point,
                // we're passing our device we select in the dialog, on to HermesBLE for the connecting.
                .flatMap(device -> HermesBLE.connectAndListen(device,
                        BLStandardAttributes.SERVICE_HEART_RATE,
                        BLStandardAttributes.CHAR_HEART_RATE_MEASUREMENT))

                // After the above runs, we'll be connected.  So, the first "event" we get will be a success.
                // Lets take out the BluetoothGatt from this event and save it.  We'll need it to clean up later.
                .doOnNext(event -> mGatt = event.gatt)

                // We also should change the color of our heart if we get a solid connection!
                .doOnNext(event -> mHeart.setColorFilter(COLOR_HEART))

                // Now that we're connected, we'll be getting events every time what we've subscribed to
                // changes.  To keep things clean, we've supplied a HeartRateEvaluator that handles the
                // byte conversion for you.  Just map it in the same way you mapped connectAndListen.
                .flatMap(event -> new HeartRateEvaluator().handle(event))

                // Finally, we're at a point where we're getting something we can use.
                // .subscribe tells the Observable to finally startup, and that after we've marched
                // through the above, we'll get a rate.  We can use this rate to set our TextView mRate.
                .subscribe(rate -> {
                    mRate.setText(String.valueOf(rate));
                });

        // We also need to make sure our dialog can be seen.  If this isn't run, then nothing shows up!.
        dialog.show(getFragmentManager(), "dialog");
    }

    /*
    onDestroy is ran every time the activity is destroyed.  This is normally the last we see of the Activity.
    Because of this, we don't want our bluetooth subscriptions to continue to run.
    We NEED to tell HermesBLE to clean up our mess.  Otherwise, good luck connecting again!
     */
    @Override
    protected void onDestroy() {
        super.onDestroy(); // Call super, because things.

        HermesBLE.close(mGatt); // Have Hermes handle closing out our bluetooth connection for us.
        mDeviceSubscription.unsubscribe(); // And unsubscribe from the dialog we created.

        // Finally, just incase we're not really closing, make sure we do - by running finish.
        finish();
    }
}

redpajama_set_name: RedPajamaGithub


text:
// [AUTO_HEADER]

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Xml;

namespace TakaoPreference
{
    /// <remarks>
    /// The helper utilities.
    /// </remarks>
    public class TakaoHelper
    {
        public static string ProjectID = "Yahoo! KeyKey";
        public static string VenderIdentifer = "com.yahoo.KeyKey";
        public static string GeneralXMLpath = TakaoHelper.GetXMLFullPath(VenderIdentifer + ".plist");
        public static string TraditionalPhoneticXMLpath = TakaoHelper.GetXMLFullPath(VenderIdentifer + ".TraditionalMandarin.plist");
        public static string SmartPhoneticXMLpath = TakaoHelper.GetXMLFullPath(VenderIdentifer + ".SmartMandarin.plist");
        public static string CangjieXMLpath = TakaoHelper.GetXMLFullPath(VenderIdentifer + ".Generic-cj-cin.plist");
        public static string SimplexXMLpath = TakaoHelper.GetXMLFullPath(VenderIdentifer + ".Generic-simplex-cin.plist");
		public static string OneKeyXMLpath = TakaoHelper.GetXMLFullPath(VenderIdentifer + ".OneKey.plist");
		public static string LegacySearchXMLpath = TakaoHelper.GetXMLFullPath(VenderIdentifer + ".Search.plist");

        /// <summary>
        /// A tool to display debug messages.
        /// </summary>
        /// <param name="theMessage"></param>
        public static void msg(string theMessage)
        {
            System.Diagnostics.Debug.WriteLine(theMessage, "Debug");
        }

        public static string GetEnvTempDir()
        {
            return Environment.GetEnvironmentVariable("TEMP");
        }

        public static string GetTempFilePath(string filename)
        {
            return TakaoHelper.GetEnvTempDir() + Path.DirectorySeparatorChar + filename;
        }

        public static string GetTempFilePathFromURL(string URL)
        {
            string filename = URL.Remove(0, URL.LastIndexOf('/') + 1);
            return TakaoHelper.GetEnvTempDir() + Path.DirectorySeparatorChar +filename;
        }

        /// <summary>
        /// A helper to generator the full path of the perference file (which is in XML format) by passing the filename.
        /// </summary>
        /// <param name="filename">The filename of the perference file.</param>
        /// <returns></returns>
        ///
        public static string GetXMLFullPath(string filename)
        {
            string confDir =
                Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) +
                Path.DirectorySeparatorChar +
                ProjectID +
                Path.DirectorySeparatorChar;

            if (!Directory.Exists(confDir))
            {
                Directory.CreateDirectory(confDir);
            }
            return confDir + filename;
        }
        #region XML related

        public static string SerializeListToString(List<string> list)
        {
            string returnString = "ARRAY:";
            int i = 0;
            foreach(string item in list)
            {
                if (i++ < list.Count)
                    returnString += item + ", ";
                else
                    returnString += item;
                //i++;
            }
            return returnString;
        }

        /// <summary>
        /// A helper to generate a dicitonary from a plist(xml) file.
        /// </summary>
        /// <param name="filename">The filename of the xml source.</param>
        /// <returns></returns>
        public static Dictionary<string, string> DictionaryFromFile(string filename)
        {
            Dictionary<string, string> dictionary = new Dictionary<string, string>();
            if(System.IO.File.Exists(filename))
            {
                try
                {
                    XmlTextReader myReader = new XmlTextReader(filename);
                    myReader.XmlResolver = null;
                    string myKey = "";
                    string myValue = "";
                    List<string> items = new List<string>();

                    while (myReader.Read())
                    {
                        if (myReader.NodeType == XmlNodeType.Element)
                        {
                            if (myReader.Name == "key")
                            {
                                myReader.Read();
                                myKey = myReader.Value.Trim();

                            }
                            if (myReader.Name == "array")
                            {
                                if (myReader.IsEmptyElement)
                                {
                                    items.Clear();
                                }
                                else
                                {
                                    while (myReader.Read() && !(myReader.NodeType == XmlNodeType.EndElement && myReader.Name == "array"))
                                    {
                                        if (myReader.NodeType == XmlNodeType.Element
                                            && myReader.Name == "string")
                                        {
                                            myReader.Read();
                                            items.Add(myReader.Value.Trim());
                                        }
                                    }
                                }
                                myValue = TakaoHelper.SerializeListToString(items);
                                TakaoHelper.msg(myValue);
                                if (myKey.Length > 0)
                                    dictionary.Add(myKey, myValue);
                                items.Clear();

                                myKey = "";
                                myValue = "";
                            }

                            if (myReader.Name == "string")
                            {
                                myReader.Read();
                                myValue = myReader.Value.Trim();
                                if (myKey.Length > 0)
                                    dictionary.Add(myKey, myValue);
                                myKey = "";
                                myValue = "";
                            }
                        }
                    }
                    myReader.Close();
                }
                catch {
                }
            }
            return dictionary;
        }

        /// <summary>
        /// Save a dictionary into an XML file by passing the dictionary object and filename
        /// </summary>
        /// <param name="dictionary">The Dictionary.</param>
        /// <param name="filename">The full path of the file to write.</param>
        public static void DictionaryToFile(Dictionary<string, string> dictionary, string filename)
        {
            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.XmlResolver = null;

            XmlDeclaration xmlDeclaration = xmlDocument.CreateXmlDeclaration("1.0", "UTF-8", "yes");
            xmlDocument.AppendChild(xmlDeclaration);

            xmlDocument.AppendChild(xmlDocument.CreateDocumentType("plist", "-//Apple//DTD PLIST 1.0//EN", "http://www.apple.com/DTDs/PropertyList-1.0.dtd", null));
            // Somehow applying DTD to the XML parser of the .Net framework
			// makes parsing slow.
            XmlElement plst = xmlDocument.CreateElement("plist");
            xmlDocument.AppendChild(plst);
            XmlElement dict = xmlDocument.CreateElement("dict");
            plst.AppendChild(dict);

            foreach (KeyValuePair<string, string> kvp in dictionary)
            {
                XmlElement theKey = xmlDocument.CreateElement("key");
                theKey.InnerText = kvp.Key.Trim();
                dict.AppendChild(theKey);

                if (kvp.Value.StartsWith("ARRAY:"))
                {
                    string stringToExplode = kvp.Value.Remove(0, 6);
                    string[] explodedStrings = stringToExplode.Split(", ".ToCharArray());
                    XmlElement theArray = xmlDocument.CreateElement("array");
                    foreach (string item in explodedStrings)
                    {
                        if (item.Length > 0)
                        {
                            XmlElement theString = xmlDocument.CreateElement("string");
                            theString.InnerText = item;
                            theArray.AppendChild(theString);
                        }
                    }
                    dict.AppendChild(theArray);
                }
                else
                {
                    XmlElement theString = xmlDocument.CreateElement("string");
                    theString.InnerText = kvp.Value.Trim();

                    if (theString.InnerText.Length == 0)
                    {
                        theString.IsEmpty = true;
                    }

                    dict.AppendChild(theString);
                }
            }
            XmlTextWriter writer = new XmlTextWriter(filename, Encoding.UTF8);
            writer.Formatting = Formatting.Indented;
            xmlDocument.WriteContentTo(writer);
            writer.Close();
        }
        /// <summary>
        /// To dump the content of a dictionary.
        /// </summary>
        /// <param name="dictionary"></param>
        public static void DumpDictionary(Dictionary<string, string> dictionary)
        {
            TakaoHelper.PrintDictionary(dictionary);
        }
        /// <summary>
        /// To dump the content of a dictionary.
        /// </summary>
        /// <param name="dictionary"></param>
        public static void PrintDictionary(Dictionary<string, string> dictionary)
        {
            foreach (KeyValuePair<string, string> kvp in dictionary)
            {
                string msg = "key: " + kvp.Key + "=> value: " + kvp.Value;
                TakaoHelper.msg(msg);
            }
        }
        #endregion
    }
}


text:
## Instalação

```js
$ npm install --save react-native-components
```

## Começando

### Como usar um componente ?

```js
import { Header, VerMaisTexto } from 'react-native-componentes';

return(
    <View>
        <Header titulo="React Native Componentes" />
        <VerMaisTexto numeroLinhas={2}>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam odio eros, auctor nec dignissim eget, condimentum in ante. In euismod laoreet molestie. Nullam dictum sed turpis vel imperdiet. Donec vel metus sed nisl mattis blandit. Sed non elit nisl.
        </VerMaisTexto>
    </View>
)
```

## Componentes

- [x] [AlbumFotos](https://github.com/vitoralvesdev/react-native-componentes/blob/master/documentacao/API/albumfotos.md)
- [x] [Busca](https://github.com/vitoralvesdev/react-native-componentes/blob/master/documentacao/API/busca.md)
- [x] [Carousel](https://github.com/vitoralvesdev/react-native-componentes/blob/master/documentacao/API/carousel.md)
- [x] [Carregando](https://github.com/vitoralvesdev/react-native-componentes/blob/master/documentacao/API/carregando.md)
- [x] [FiltroModal](https://github.com/vitoralvesdev/react-native-componentes/blob/master/documentacao/API/filtromodal.md)
- [x] [GaleriaFotos](https://github.com/vitoralvesdev/react-native-componentes/blob/master/documentacao/API/galeriafotos.md)
- [x] [Header](https://github.com/vitoralvesdev/react-native-componentes/blob/master/documentacao/API/header.md)
- [x] [MenuItem](https://github.com/vitoralvesdev/react-native-componentes/blob/master/documentacao/API/menuitem.md)
- [x] [Paginacao](https://github.com/vitoralvesdev/react-native-componentes/blob/master/documentacao/API/paginacao.md)
- [x] [VerMaisTexto](https://github.com/vitoralvesdev/react-native-componentes/blob/master/documentacao/API/vermaistexto.md)
- [ ] SwiperMenu

## Atualizações

- [V0.0.7](https://github.com/vitoralvesdev/react-native-componentes/releases/tag/0.0.7) - Novos componentes para integrar com seu projeto.
- [V0.0.9](https://github.com/vitoralvesdev/react-native-componentes/releases/tag/0.0.9) - Correção de diversos bugs do Carousel.
- [V0.0.10](https://github.com/vitoralvesdev/react-native-componentes/releases/tag/0.0.10) - Nova propriedade no Carousel.
- [V0.0.11](https://github.com/vitoralvesdev/react-native-componentes/releases/tag/0.0.11) - Correção de diversos bugs. Header agora é animado.

## Contribua

### Como contribuir para o projeto ?

- Crie uma branch a partir da master com o nome do componente ou funcionalidade nova.
- Crie o pull request.

### Requisitos mínimos

1. Crie uma documentação para o seu componente em `documentacao/API/seucomponente.md`.
- Escreva uma introdução falando sobre o componente.
- Adicione uma imagem ou gif se seu componente tiver alguma animação.
- Crie uma tabela das propriedades, padrões, tipagem e descrição do componente.

2. Crie um arquivo de exemplo utilizando seu componente em `exemplos/ExemploSeuComponente.js`

### Encontrou alguma coisa errada e quer fazer a correção?

- Crie uma branch a partir da master com o nome da correção.
- Crie o pull request.

## Objetivo com o projeto

Criei este projeto para ajudar no dia a dia do programador, estou feliz em aceitar sugestões, correções ou funcionalidades novas (:


text:
<?php
namespace tests\application\sitemaps\MappingA;
use mocks\application\sitemaps\MapFixture;

/**
 * @covers \vsc\application\sitemaps\MappingA::isStatic()
 */
class isStatic extends \BaseUnitTest
{
	public function testNotStatic()
	{
		$o = new MappingA_underTest_isStatic();
		$this->assertFalse($o->isStatic());
	}
}

class MappingA_underTest_isStatic extends MapFixture {
	public function __construct ($sPath = null, $sRegex = null) {
		if (is_null($sPath)) {
			$sPath = __FILE__;
		}
		if (is_null($sRegex)) {
			$sRegex = '.*';
		}
		parent::__construct($sPath, $sRegex);
	}
}


text:
#include "TopicMetadataImpl.h"

namespace pulsar {
TopicMetadataImpl::TopicMetadataImpl(const int numPartitions) : numPartitions_(numPartitions) {}

int TopicMetadataImpl::getNumPartitions() const { return numPartitions_; }
}  // namespace pulsar


text:
var gulp     = require("gulp");
var mocha    = require("gulp-mocha");
var clean    = require("gulp-clean");
var jshint   = require("gulp-jshint");
var stylish  = require("jshint-stylish");
var sequence = require("run-sequence");

var imageResize = require("./index.js");

gulp.task("jshint", function () {
  gulp.src(["gulpfile.js", "index.js", "test/*.js"])
    .pipe(jshint())
    .pipe(jshint.reporter(stylish));
});

gulp.task("clean", function () {
  gulp.src("tmp/*", { read : false })
    .pipe(clean());
});

gulp.task("mocha", ["image_resize"], function () {
  return gulp.src("test/*_test.js")
    .pipe(mocha({ reporter: "spec" }));
});

var resizeTasks = [];

var resize = function(files, key, options) {

  function makeTask(files, key, options) {
    gulp.task("image_resize:" + key, function () {
      return gulp.src(files)
        .pipe(imageResize(options))
        .pipe(gulp.dest("tmp/" + key));
    });
    resizeTasks.push("image_resize:" + key);
  }

  makeTask(files, key, options);

  var imOptions = { imageMagick : true };
  for (var k in options) { imOptions[k] = options[k]; }
  makeTask(files, key + "_imagemagick", imOptions);
};

resize([
  "test/fixtures/gnu.jpg",
  "test/fixtures/wikipedia.png",
  "test/fixtures/Rhododendron.jpg",
  "test/fixtures/TeslaTurbine.png"
], "resize", {
  width: 100
});

resize("test/fixtures/wikipedia.png", "upscale", {
  width: 600,
  height: 0,
  upscale: true
});

resize("test/fixtures/wikipedia.png", "upscale2", {
  width: 600,
  height: 600,
  upscale: true
});

resize("test/fixtures/wikipedia.png", "no_upscale", {
  width: 600,
  upscale: false
});

resize("test/fixtures/wikipedia.png", "no_upscale2", {
  width: 100,
  height: 600,
  upscale: false
});

resize("test/fixtures/wikipedia.png", "crop", {
  width: 400,
  height: 300,
  upscale: false,
  crop: true
});

resize("test/fixtures/wikipedia.png", "crop_gravity", {
  width: 400,
  height: 300,
  upscale: false,
  crop: true,
  gravity: "NorthWest"
});

resize("test/fixtures/wikipedia.png", "crop_width_only", {
  width: 300,
  crop: true
});

resize("test/fixtures/Rhododendron.jpg", "quality", {
  width: 600,
  height: 0,
  upscale: false,
  quality: 0.2
});

resize("test/fixtures/Rhododendron.jpg", "sharpen", {
  width: 600,
  height: 0,
  sharpen: true
});

resize("test/fixtures/Rhododendron.jpg", "filter", {
  width: 600,
  height: 0,
  filter: "catrom"
});

resize("test/fixtures/Rhododendron.jpg", "samplingFactor", {
  width: 600,
  height: 0,
  samplingFactor: [2,2]
});

resize("test/fixtures/wikipedia.png", "convert", {
  format: "jpg"
});

gulp.task("image_resize", resizeTasks);

gulp.task("test", function(callback) {
  sequence("clean", "jshint", "mocha", callback);
});

gulp.task("default", ["test"]);


text:
using namespace llvm;

#define DEBUG_TYPE "xfer"

namespace llvm {
  FunctionPass *createHexagonSplitConst32AndConst64();
  void initializeHexagonSplitConst32AndConst64Pass(PassRegistry&);
}

namespace {
  class HexagonSplitConst32AndConst64 : public MachineFunctionPass {
  public:
    static char ID;
    HexagonSplitConst32AndConst64() : MachineFunctionPass(ID) {
      PassRegistry &R = *PassRegistry::getPassRegistry();
      initializeHexagonSplitConst32AndConst64Pass(R);
    }
    StringRef getPassName() const override {
      return "Hexagon Split Const32s and Const64s";
    }
    bool runOnMachineFunction(MachineFunction &Fn) override;
    MachineFunctionProperties getRequiredProperties() const override {
      return MachineFunctionProperties().set(
          MachineFunctionProperties::Property::NoVRegs);
    }
  };
}

char HexagonSplitConst32AndConst64::ID = 0;

INITIALIZE_PASS(HexagonSplitConst32AndConst64, "split-const-for-sdata",
      "Hexagon Split Const32s and Const64s", false, false)

bool HexagonSplitConst32AndConst64::runOnMachineFunction(MachineFunction &Fn) {
  auto &HST = Fn.getSubtarget<HexagonSubtarget>();
  auto &HTM = static_cast<const HexagonTargetMachine&>(Fn.getTarget());
  auto &TLOF = *HTM.getObjFileLowering();
  if (HST.useSmallData() && TLOF.isSmallDataEnabled(HTM))
    return false;

  const TargetInstrInfo *TII = HST.getInstrInfo();
  const TargetRegisterInfo *TRI = HST.getRegisterInfo();

  // Loop over all of the basic blocks
  for (MachineBasicBlock &B : Fn) {
    for (auto I = B.begin(), E = B.end(); I != E; ) {
      MachineInstr &MI = *I;
      ++I;
      unsigned Opc = MI.getOpcode();

      if (Opc == Hexagon::CONST32) {
        unsigned DestReg = MI.getOperand(0).getReg();
        uint64_t ImmValue = MI.getOperand(1).getImm();
        const DebugLoc &DL = MI.getDebugLoc();
        BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), DestReg)
            .addImm(ImmValue);
        B.erase(&MI);
      } else if (Opc == Hexagon::CONST64) {
        unsigned DestReg = MI.getOperand(0).getReg();
        int64_t ImmValue = MI.getOperand(1).getImm();
        const DebugLoc &DL = MI.getDebugLoc();
        unsigned DestLo = TRI->getSubReg(DestReg, Hexagon::isub_lo);
        unsigned DestHi = TRI->getSubReg(DestReg, Hexagon::isub_hi);

        int32_t LowWord = (ImmValue & 0xFFFFFFFF);
        int32_t HighWord = (ImmValue >> 32) & 0xFFFFFFFF;

        BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), DestLo)
            .addImm(LowWord);
        BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), DestHi)
            .addImm(HighWord);
        B.erase(&MI);
      }
    }
  }

  return true;
}

//===----------------------------------------------------------------------===//
//                         Public Constructor Functions
//===----------------------------------------------------------------------===//
FunctionPass *llvm::createHexagonSplitConst32AndConst64() {
  return new HexagonSplitConst32AndConst64();
}


text:
import Request from '../utils/Request';
import NewsItem from './NewsItem';

export default class NewsList {
  constructor(options) {
    const defaults = {
      list: [],
      source: 'bbc-news'
    };

    this.options = Object.assign({}, options, defaults);
    this.list = this.options.list;
  }

  fetchNews(callback) {
    const url = 'https://newsapi.org/v1/articles';
    const params = {
      source: this.options.source,
      sortBy: 'top',
      apiKey: '1572bab4c54248c483304c26bfa71b8e'
    };
    const queryString = Object.keys(params).map(key => `${key}=${params[key]}`).join('&');

    return Request.getData(`${url}?${queryString}`)
      .then(callback)
      .catch(console.error);
  }

  addNews(news) {
    this.list = this.list.concat(news);
  }

  getNewsListFragment() {
    const fragment = document.createDocumentFragment();

    this.list.forEach(news => {
      fragment.appendChild(new NewsItem(news));
    });

    return fragment;
  }
}


text:
require 'manatee/rails/helper'
require 'manatee/rails/handler'
require 'manatee/rails/resolver'
require 'manatee/rails/extensions'
require 'manatee/rails/hash_visitor'
require 'manatee/rails/routes_compiler'


text:
module Fog
  module Compute
    class VcloudDirector
      class Real
        # Retrieve an administrative view of a cloud.
        #
        # The VCloud element provides access to cloud-wide namespace of objects
        # that an administrator can view and, in most cases, modify.
        #
        # @return [Excon:Response]
        #   * body<~Hash>:
        #     * :href<~String> - The URI of the entity.
        #     * :type<~String> - The MIME type of the entity.
        #     * :name<~String> - The name of the entity.
        #     * :Description<~String> - Optional description.
        #     * :OrganizationReferences<Hash>:
        #       * :OrganizationReference<~Array<Hash>>:
        #         * :href<~String> - Contains the URI to the entity.
        #         * :name<~String> - Contains the name of the entity.
        #         * :type<~String> - Contains the type of the entity.
        #     * :ProviderVdcReferences<~Hash>:
        #       * :ProviderVdcReferences<~Array<Hash>>:
        #     * :RightReferences<~Hash>:
        #       * :RightReferences<~Array<Hash>>:
        #     * :RoleReferences<~Hash>:
        #       * :RoleReferences<~Array<Hash>>:
        #     * :Networks<~Hash>:
        #       * :Network<~Array<Hash>>:
        #
        # @see http://pubs.vmware.com/vcd-51/topic/com.vmware.vcloud.api.reference.doc_51/doc/operations/GET-Vcloud.html
        # @since vCloud API version 0.9
        def get_vcloud
          response = request(
            :expects    => 200,
            :idempotent => true,
            :method     => 'GET',
            :parser     => Fog::ToHashDocument.new,
            :path       => 'admin/'
          )
          ensure_list! response.body, :OrganizationReferences, :OrganizationReference
          ensure_list! response.body, :ProviderVdcReferences, :ProviderVdcReference
          ensure_list! response.body, :RightReferences, :RightReference
          ensure_list! response.body, :RoleReferences, :RoleReference
          ensure_list! response.body, :Networks, :Network
          response
        end
      end

      class Mock
        def get_vcloud
          body =
            {:href=>make_href('admin/'),
             :type=>"application/vnd.vmware.admin.vcloud+xml",
             :name=>'VMware vCloud Director',
             :Description=>'5.1.2.1377223 Tue Oct 15 20:56:05 GMT 2013',
             :Tasks=>{:Task=>[]},
             :OrganizationReferences=>
              {:OrganizationReference=>
               [{:type=>"application/vnd.vmware.admin.organization+xml",
                 :name=>data[:org][:name],
                 :href=>make_href("api/admin/org/#{data[:org][:uuid]}")}]},
             :ProviderVdcReferences=>{:ProviderVdcReference=>[]},
             :RightReferences=>{:RightReference=>[]},
             :RoleReferences=>{:RoleReference=>[]},
             :Networks=>{:Network=>[]}}

          Excon::Response.new(
            :body    => body,
            :headers => {'Content-Type' => "#{body[:type]};version=#{api_version}"},
            :status  => 200
          )
        end
      end
    end
  end
end


text:
package com.chrisfolger.needsmoredojo.testutil;

import com.intellij.lang.ASTNode;
import com.intellij.lang.javascript.psi.impl.JSReferenceExpressionImpl;

import static org.mockito.Mockito.mock;

public class MockJSReferenceExpression extends JSReferenceExpressionImpl
{
    private String referencedName;

    public MockJSReferenceExpression(String referencedName) {
        super(mock(ASTNode.class));

        this.referencedName = referencedName;
    }

    @Override
    public String getReferencedName()
    {
        return referencedName;
    }
}


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">

		<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
		<title>SLF4J 1.6.1 Reference</title>
		<link rel="stylesheet" type="text/css" href="stylesheet.css" title="style" />

			All Classes

Packages

				integrator

				org.apache.commons.logging

				org.apache.commons.logging.impl

				org.apache.log4j

				org.dummy

				org.slf4j

				org.slf4j.bridge

				org.slf4j.cal10n_dummy

				org.slf4j.dummyExt

				org.slf4j.helpers

				org.slf4j.impl

				org.slf4j.instrumentation

				org.slf4j.migrator

				org.slf4j.migrator.helper

				org.slf4j.migrator.internal

				org.slf4j.migrator.line

				org.slf4j.profiler

				org.slf4j.test_osgi


text:
/* @flow */

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import { getFirstIcon } from '../../../../utils/toolbar';
import Option from '../../../Option';
import { Dropdown, DropdownOption } from '../../../Dropdown';

import styles from './styles.css'; // eslint-disable-line no-unused-vars

export default class Inline extends Component {

  static propTypes = {
    expanded: PropTypes.bool,
    doExpand: PropTypes.func,
    doCollapse: PropTypes.func,
    onExpandEvent: PropTypes.func,
    config: PropTypes.object,
    onChange: PropTypes.func,
    currentState: PropTypes.object,
  };

  renderInFlatList(): Object {
    const { config, currentState, onChange } = this.props;
    return (
      <div className={classNames('rdw-inline-wrapper', config.className)} aria-label="rdw-inline-control">
        {
          config.options
          .map((style, index) =>
            <Option
              key={index}
              value={style}
              onClick={onChange}
              className={classNames(config[style].className)}
              active={
                currentState[style] === true ||
                (style === 'MONOSPACE' && currentState['CODE'])
              }
            >
              <img
                alt=""
                src={config[style].icon}
              />
            </Option>
          )
        }
      </div>
    );
  }

  renderInDropDown(): Object {
    const {
      config,
      expanded,
      doExpand,
      onExpandEvent,
      doCollapse,
      currentState,
      onChange,
    } = this.props;
    const { className, dropdownClassName } = config;
    return (
      <Dropdown
        className={classNames('rdw-inline-dropdown', className)}
        optionWrapperClassName={classNames(dropdownClassName)}
        onChange={onChange}
        expanded={expanded}
        doExpand={doExpand}
        doCollapse={doCollapse}
        onExpandEvent={onExpandEvent}
        aria-label="rdw-inline-control"
      >
        <img
          src={getFirstIcon(config)}
          alt=""
        />
        {
          config.options
          .map((style, index) =>
            <DropdownOption
              key={index}
              value={style}
              className={classNames('rdw-inline-dropdownoption', config[style].className)}
              active={
                currentState[style] === true ||
                (style === 'MONOSPACE' && currentState['CODE'])
              }
            >
              <img
                src={config[style].icon}
                alt=""
              />
            </DropdownOption>)
          }
      </Dropdown>
    );
  }

  render(): Object {
    const { config: { inDropdown } } = this.props;
    if (inDropdown) {
      return this.renderInDropDown();
    }
    return this.renderInFlatList();
  }
}

// todo: make subscript less low


text:
<!DOCTYPE html>

        <meta charset='utf-8'>
        <title>CS-419 Xi Tower Defense</title>
        <link href="content/startStyle.css" rel="stylesheet" type="text/css">

        <audio id = "startBGM" autoplay loop><source src="content/sounds/bgm/startBGM.mp3"></audio>

Xi Tower Defense Start Game!


text:
package etcd

import (
	"testing"

	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/apis/experimental"
	"k8s.io/kubernetes/pkg/fields"
	"k8s.io/kubernetes/pkg/labels"
	"k8s.io/kubernetes/pkg/registry/registrytest"
	"k8s.io/kubernetes/pkg/runtime"
	"k8s.io/kubernetes/pkg/tools"
	"k8s.io/kubernetes/pkg/util"
)

func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
	etcdStorage, fakeClient := registrytest.NewEtcdStorage(t, "experimental")
	ingressStorage := NewREST(etcdStorage)
	return ingressStorage, fakeClient
}

var (
	namespace           = api.NamespaceNone
	name                = "foo-ingress"
	defaultHostname     = "foo.bar.com"
	defaultBackendName  = "default-backend"
	defaultBackendPort  = util.IntOrString{Kind: util.IntstrInt, IntVal: 80}
	defaultLoadBalancer = "127.0.0.1"
	defaultPath         = "/foo"
	defaultPathMap      = map[string]string{defaultPath: defaultBackendName}
)

type IngressRuleValues map[string]string

func toHTTPIngressPaths(pathMap map[string]string) []experimental.HTTPIngressPath {
	httpPaths := []experimental.HTTPIngressPath{}
	for path, backend := range pathMap {
		httpPaths = append(httpPaths, experimental.HTTPIngressPath{
			Path: path,
			Backend: experimental.IngressBackend{
				ServiceName: backend,
				ServicePort: defaultBackendPort,
			},
		})
	}
	return httpPaths
}

func toIngressRules(hostRules map[string]IngressRuleValues) []experimental.IngressRule {
	rules := []experimental.IngressRule{}
	for host, pathMap := range hostRules {
		rules = append(rules, experimental.IngressRule{
			Host: host,
			IngressRuleValue: experimental.IngressRuleValue{
				HTTP: &experimental.HTTPIngressRuleValue{
					Paths: toHTTPIngressPaths(pathMap),
				},
			},
		})
	}
	return rules
}

func newIngress(pathMap map[string]string) *experimental.Ingress {
	return &experimental.Ingress{
		ObjectMeta: api.ObjectMeta{
			Name:      name,
			Namespace: namespace,
		},
		Spec: experimental.IngressSpec{
			Backend: &experimental.IngressBackend{
				ServiceName: defaultBackendName,
				ServicePort: defaultBackendPort,
			},
			Rules: toIngressRules(map[string]IngressRuleValues{
				defaultHostname: pathMap,
			}),
		},
		Status: experimental.IngressStatus{
			LoadBalancer: api.LoadBalancerStatus{
				Ingress: []api.LoadBalancerIngress{
					{IP: defaultLoadBalancer},
				},
			},
		},
	}
}

func validIngress() *experimental.Ingress {
	return newIngress(defaultPathMap)
}

func TestCreate(t *testing.T) {
	storage, fakeClient := newStorage(t)
	test := registrytest.New(t, fakeClient, storage.Etcd)
	ingress := validIngress()
	noDefaultBackendAndRules := validIngress()
	noDefaultBackendAndRules.Spec.Backend = &experimental.IngressBackend{}
	noDefaultBackendAndRules.Spec.Rules = []experimental.IngressRule{}
	badPath := validIngress()
	badPath.Spec.Rules = toIngressRules(map[string]IngressRuleValues{
		"foo.bar.com": {"/invalid[": "svc"}})
	test.TestCreate(
		// valid
		ingress,
		noDefaultBackendAndRules,
		badPath,
	)
}

func TestUpdate(t *testing.T) {
	storage, fakeClient := newStorage(t)
	test := registrytest.New(t, fakeClient, storage.Etcd)
	test.TestUpdate(
		// valid
		validIngress(),
		// updateFunc
		func(obj runtime.Object) runtime.Object {
			object := obj.(*experimental.Ingress)
			object.Spec.Rules = toIngressRules(map[string]IngressRuleValues{
				"bar.foo.com": {"/bar": defaultBackendName},
			})
			return object
		},
		// invalid updateFunc: ObjeceMeta is not to be tampered with.
		func(obj runtime.Object) runtime.Object {
			object := obj.(*experimental.Ingress)
			object.UID = "newUID"
			return object
		},

		func(obj runtime.Object) runtime.Object {
			object := obj.(*experimental.Ingress)
			object.Name = ""
			return object
		},

		func(obj runtime.Object) runtime.Object {
			object := obj.(*experimental.Ingress)
			object.Spec.Rules = toIngressRules(map[string]IngressRuleValues{
				"foo.bar.com": {"/invalid[": "svc"}})
			return object
		},
	)
}

func TestDelete(t *testing.T) {
	storage, fakeClient := newStorage(t)
	test := registrytest.New(t, fakeClient, storage.Etcd)
	test.TestDelete(validIngress())
}

func TestGet(t *testing.T) {
	storage, fakeClient := newStorage(t)
	test := registrytest.New(t, fakeClient, storage.Etcd)
	test.TestGet(validIngress())
}

func TestList(t *testing.T) {
	storage, fakeClient := newStorage(t)
	test := registrytest.New(t, fakeClient, storage.Etcd)
	test.TestList(validIngress())
}

func TestWatch(t *testing.T) {
	storage, fakeClient := newStorage(t)
	test := registrytest.New(t, fakeClient, storage.Etcd)
	test.TestWatch(
		validIngress(),
		// matching labels
		[]labels.Set{},
		// not matching labels
		[]labels.Set{
			{"a": "c"},
			{"foo": "bar"},
		},
		// matching fields
		[]fields.Set{
			{"metadata.name": name},
		},
		// not matching fields
		[]fields.Set{
			{"metadata.name": "bar"},
			{"name": name},
		},
	)
}