text:
package co.cask.cdap.common.lang;

import co.cask.cdap.api.annotation.Beta;
import co.cask.cdap.api.annotation.Property;
import co.cask.cdap.api.app.Application;
import co.cask.cdap.api.app.ApplicationConfigurer;
import co.cask.cdap.api.common.Bytes;
import co.cask.cdap.common.io.Locations;
import co.cask.cdap.common.lang.jar.BundleJarUtil;
import co.cask.cdap.internal.io.SchemaGenerator;
import co.cask.cdap.internal.test.AppJarHelper;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.gson.Gson;
import org.apache.twill.api.ClassAcceptor;
import org.apache.twill.filesystem.LocalLocationFactory;
import org.apache.twill.filesystem.Location;
import org.apache.twill.internal.ApplicationBundler;
import org.junit.Assert;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import java.io.File;
import java.io.IOException;
import java.net.URL;

/**
 * Unit test for ClassLoader.
 */
public class ClassLoaderTest {

  @ClassRule
  public static final TemporaryFolder TMP_FOLDER = new TemporaryFolder();

  @Test
  public void testPackageFilter() throws ClassNotFoundException {
    ClassLoader classLoader = new PackageFilterClassLoader(getClass().getClassLoader(), new Predicate<String>() {
      @Override
      public boolean apply(String input) {
        return input.startsWith("co.cask.cdap.api.");
      }
    });

    // Load allowed class. It should gives the same class.
    Class<?> cls = classLoader.loadClass(Application.class.getName());
    Assert.assertSame(Application.class, cls);

    // Try to load forbidden class. It should fail.
    try {
      classLoader.loadClass(SchemaGenerator.class.getName());
      Assert.fail();
    } catch (ClassNotFoundException e) {
      // Expected
    }

    // Load resource. Should succeed.
    Assert.assertNotNull(classLoader.getResource("logback-test.xml"));

    // Load class resource that is in the allowed package. Should succeed.
    String resourceName = Application.class.getName().replace('.', '/') + ".class";
    URL url = classLoader.getResource(resourceName);
    Assert.assertNotNull(url);
    Assert.assertEquals(getClass().getClassLoader().getResource(resourceName), url);

    // Load class resource that is in allowed package. Should return null.
    resourceName = SchemaGenerator.class.getName().replace('.', '/') + ".class";
    Assert.assertNull(classLoader.getResource(resourceName));
  }

  @Test
  public void testCombineClassLoader() throws ClassNotFoundException {
    // Creates a CombineClassLoader with two delegates.
    // One allows "co.cask.cdap.api.app", the other allows "co.cask.cdap.api.annotation"
    ClassLoader parent = getClass().getClassLoader();
    ClassLoader classLoader = new CombineClassLoader(null, ImmutableList.of(
      new PackageFilterClassLoader(parent, Predicates.equalTo(Application.class.getPackage().getName())),
      new PackageFilterClassLoader(parent, Predicates.equalTo(Beta.class.getPackage().getName()))
    ));

    // Should be able to load classes from those two packages
    Assert.assertSame(ApplicationConfigurer.class, classLoader.loadClass(ApplicationConfigurer.class.getName()));
    Assert.assertSame(Property.class, classLoader.loadClass(Property.class.getName()));

    // For classes not in those packages would failed.
    try {
      classLoader.loadClass(Bytes.class.getName());
      Assert.fail();
    } catch (ClassNotFoundException e) {
      // Expected
    }
  }

  @Test
  public void testWeakReferenceClassLoader() throws Exception {
    // Creates a jar that has Application class in it.
    Location jar = AppJarHelper.createDeploymentJar(new LocalLocationFactory(TMP_FOLDER.newFolder()),
                                                    ClassLoaderTest.class);
    // Create a class loader that load from that jar.
    File unpackDir = TMP_FOLDER.newFolder();
    BundleJarUtil.unJar(jar, unpackDir);
    ClassLoader cl = new DirectoryClassLoader(unpackDir, null, "lib");

    // Wrap it with the WeakReference ClassLoader
    ClassLoader classLoader = new WeakReferenceDelegatorClassLoader(cl);

    // Load class from the wrapped ClassLoader, should succeed and should be loaded by the delegating ClassLoader.
    Class<?> cls = classLoader.loadClass(ClassLoaderTest.class.getName());
    Assert.assertSame(cl, cls.getClassLoader());
    Assert.assertSame(cl, Delegators.getDelegate(classLoader, ClassLoader.class));

    // There is no good way to test the GC of the weak reference referent since it depends on GC.
  }

  @Test
  public void testExtraClassPath() throws IOException, ClassNotFoundException {
    File tmpDir = TMP_FOLDER.newFolder();

    // Create two jars, one with guava, one with gson
    ApplicationBundler bundler = new ApplicationBundler(new ClassAcceptor());
    Location guavaJar = Locations.toLocation(new File(tmpDir, "guava.jar"));
    bundler.createBundle(guavaJar, ImmutableList.class);

    Location gsonJar = Locations.toLocation(new File(tmpDir, "gson.jar"));
    bundler.createBundle(gsonJar, Gson.class);

    // Unpack them
    File guavaDir = BundleJarUtil.unJar(guavaJar, TMP_FOLDER.newFolder());
    File gsonDir = BundleJarUtil.unJar(gsonJar, TMP_FOLDER.newFolder());

    // Create a DirectoryClassLoader using guava dir as the main directory, with the gson dir in the extra classpath
    String extraClassPath = gsonDir.getAbsolutePath() + File.pathSeparatorChar + gsonDir.getAbsolutePath() + "/lib/*";
    ClassLoader cl = new DirectoryClassLoader(guavaDir, extraClassPath, null, "lib");

    // Should be able to load both guava and gson class from the class loader
    cl.loadClass(ImmutableList.class.getName());
    cl.loadClass(Gson.class.getName());
  }
}


text:
=== HEAD

=== 0.5.0 (July 7, 2014)

* Update Karma modules in generated package.
* Update `flight` to ^1.2.0.

=== 0.4.0 (January 18, 2014)

* Remove scaffold's dependency on globally installed Karma.
* Update `yeoman-generator` to 0.16.x.
* Update `jasmine-flight` to 2.2.x.

=== 0.3.1 (January 14, 2014)

* Specify a version range for `jasmine-jquery` and `jasmine-flight`.
* Add `grunt` and `grunt-bump` to the generated package to help automate new package releases.

=== 0.3.0 (August 26, 2013)

* Use Karma 0.10.x in the generated package.

=== 0.2.1 (August 25, 2013)

* Add `main` property to generated `bower.json`.

=== 0.2.0 (August 6, 2013)

* Specify `yo` and `karma` as peerDependencies.
* Update to Flight `~1.1.0` in generated module.
* Improve title of generated CONTRIBUTING.md.
* Add `spyOnEvent` as predefined global in .jshintrc.

=== 0.1.0 (July 9, 2013)

* Initial public release.

redpajama_set_name: RedPajamaGithub


text:
package org.cyclops.integrateddynamics.part.aspect;

import org.cyclops.integrateddynamics.IntegratedDynamics;
import org.cyclops.integrateddynamics.api.part.aspect.IAspectRegistry;
import org.cyclops.integrateddynamics.part.aspect.read.fluid.*;
import org.cyclops.integrateddynamics.part.aspect.read.inventory.*;
import org.cyclops.integrateddynamics.part.aspect.read.minecraft.AspectReadIntegerMinecraftPlayerCount;
import org.cyclops.integrateddynamics.part.aspect.read.minecraft.AspectReadIntegerMinecraftRandom;
import org.cyclops.integrateddynamics.part.aspect.read.minecraft.AspectReadIntegerMinecraftTicktime;
import org.cyclops.integrateddynamics.part.aspect.read.network.*;
import org.cyclops.integrateddynamics.part.aspect.read.redstone.*;
import org.cyclops.integrateddynamics.part.aspect.read.world.*;
import org.cyclops.integrateddynamics.part.aspect.write.AspectWriteBooleanRedstone;
import org.cyclops.integrateddynamics.part.aspect.write.AspectWriteIntegerRedstone;

/**
 * Collection of all aspects.
 * @author rubensworks
 */
public class Aspects {

    public static final IAspectRegistry REGISTRY = IntegratedDynamics._instance.getRegistryManager().getRegistry(IAspectRegistry.class);

    public static void load() {}

    // --------------- Read ---------------
    // --- Redstone ---
    public static final AspectReadBooleanRedstoneLow READ_BOOLEAN_REDSTONE_LOW = new AspectReadBooleanRedstoneLow();
    public static final AspectReadBooleanRedstoneNonLow READ_BOOLEAN_REDSTONE_NONLOW = new AspectReadBooleanRedstoneNonLow();
    public static final AspectReadBooleanRedstoneHigh READ_BOOLEAN_REDSTONE_HIGH = new AspectReadBooleanRedstoneHigh();

    public static final AspectReadIntegerRedstoneValue READ_INTEGER_REDSTONE_VALUE = new AspectReadIntegerRedstoneValue();
    public static final AspectReadIntegerRedstoneComparator READ_INTEGER_REDSTONE_COMPARATOR = new AspectReadIntegerRedstoneComparator();

    // --- Inventory ---
    public static final AspectReadBooleanInventoryFull READ_BOOLEAN_INVENTORY_FULL = new AspectReadBooleanInventoryFull();
    public static final AspectReadBooleanInventoryEmpty READ_BOOLEAN_INVENTORY_EMPTY = new AspectReadBooleanInventoryEmpty();
    public static final AspectReadBooleanInventoryNonEmpty READ_BOOLEAN_INVENTORY_NONEMPTY = new AspectReadBooleanInventoryNonEmpty();
    public static final AspectReadBooleanInventoryApplicable READ_BOOLEAN_INVENTORY_APPLICABLE = new AspectReadBooleanInventoryApplicable();

    public static final AspectReadIntegerInventoryCount READ_INTEGER_INVENTORY_COUNT = new AspectReadIntegerInventoryCount();

    public static final AspectReadListInventoryItemStacks READ_LIST_INVENTORY_ITEMSTACKS = new AspectReadListInventoryItemStacks();

    public static final AspectReadObjectItemStackInventorySlot READ_OBJECT_ITEM_STACK_INVENTORY_SLOT = new AspectReadObjectItemStackInventorySlot();

    // --- World ---
    public static final AspectReadBooleanWorldBlock READ_BOOLEAN_WORLD_BLOCK = new AspectReadBooleanWorldBlock();
    public static final AspectReadBooleanWorldWeatherClear READ_BOOLEAN_WORLD_WEATHER_CLEAR = new AspectReadBooleanWorldWeatherClear();
    public static final AspectReadBooleanWorldWeatherRaining READ_BOOLEAN_WORLD_WEATHER_RAINING = new AspectReadBooleanWorldWeatherRaining();
    public static final AspectReadBooleanWorldWeatherThunder READ_BOOLEAN_WORLD_WEATHER_THUNDER = new AspectReadBooleanWorldWeatherThunder();
    public static final AspectReadBooleanWorldIsDay READ_BOOLEAN_WORLD_ISDAY = new AspectReadBooleanWorldIsDay();
    public static final AspectReadBooleanWorldIsNight READ_BOOLEAN_WORLD_ISNIGHT = new AspectReadBooleanWorldIsNight();

    public static final AspectReadIntegerWorldRainCountdown READ_INTEGER_WORLD_RAINCOUNTDOWN = new AspectReadIntegerWorldRainCountdown();
    public static final AspectReadIntegerWorldTicktime READ_INTEGER_WORLD_TICKTIME = new AspectReadIntegerWorldTicktime();
    public static final AspectReadIntegerWorldDayTime READ_INTEGER_WORLD_DAYTIME = new AspectReadIntegerWorldDayTime();
    public static final AspectReadIntegerWorldLightLevel READ_INTEGER_WORLD_LIGHT_LEVEL = new AspectReadIntegerWorldLightLevel();
    public static final AspectReadIntegerWorldPlayerCount READ_INTEGER_WORLD_PLAYERCOUNT = new AspectReadIntegerWorldPlayerCount();
    public static final AspectReadIntegerWorldDimension READ_INTEGER_WORLD_DIMENSION = new AspectReadIntegerWorldDimension();
    public static final AspectReadIntegerWorldPosX READ_INTEGER_WORLD_POSX = new AspectReadIntegerWorldPosX();
    public static final AspectReadIntegerWorldPosY READ_INTEGER_WORLD_POSY = new AspectReadIntegerWorldPosY();
    public static final AspectReadIntegerWorldPosZ READ_INTEGER_WORLD_POSZ = new AspectReadIntegerWorldPosZ();

    public static final AspectReadLongWorldTime READ_LONG_WORLD_TIME = new AspectReadLongWorldTime();
    public static final AspectReadLongWorldTotalTime READ_LONG_WORLD_TOTALTIME = new AspectReadLongWorldTotalTime();

    public static final AspectReadStringWorldName READ_STRING_WORLD_NAME = new AspectReadStringWorldName();

    public static final AspectReadObjectBlockWorld READ_OBJECT_BLOCK_WORLD_BLOCK = new AspectReadObjectBlockWorld();

    public static final AspectReadListWorldEntities READ_LIST_WORLD_ENTITIES = new AspectReadListWorldEntities();

    // --- Fluid ---
    public static final AspectReadBooleanFluidFull READ_BOOLEAN_FLUID_FULL = new AspectReadBooleanFluidFull();
    public static final AspectReadBooleanFluidEmpty READ_BOOLEAN_FLUID_EMPTY = new AspectReadBooleanFluidEmpty();
    public static final AspectReadBooleanFluidNonEmpty READ_BOOLEAN_FLUID_NONEMPTY = new AspectReadBooleanFluidNonEmpty();
    public static final AspectReadBooleanFluidApplicable READ_BOOLEAN_FLUID_APPLICABLE = new AspectReadBooleanFluidApplicable();
    public static final AspectReadBooleanFluidGaseous READ_BOOLEAN_FLUID_GASEOUS = new AspectReadBooleanFluidGaseous();

    public static final AspectReadIntegerFluidAmount READ_INTEGER_FLUID_AMOUNT = new AspectReadIntegerFluidAmount();
    public static final AspectReadIntegerFluidAmountTotal READ_INTEGER_FLUID_AMOUNTTOTAL = new AspectReadIntegerFluidAmountTotal();
    public static final AspectReadIntegerFluidCapacity READ_INTEGER_FLUID_CAPACITY = new AspectReadIntegerFluidCapacity();
    public static final AspectReadIntegerFluidCapacityTotal READ_INTEGER_FLUID_CAPACITYTOTAL = new AspectReadIntegerFluidCapacityTotal();
    public static final AspectReadIntegerFluidTanks READ_INTEGER_FLUID_TANKS = new AspectReadIntegerFluidTanks();
    public static final AspectReadIntegerFluidDensity READ_INTEGER_FLUID_DENSITY = new AspectReadIntegerFluidDensity();
    public static final AspectReadIntegerFluidLuminosity READ_INTEGER_FLUID_LUMINOSITY = new AspectReadIntegerFluidLuminosity();
    public static final AspectReadIntegerFluidTemperature READ_INTEGER_FLUID_TEMPERATURE = new AspectReadIntegerFluidTemperature();
    public static final AspectReadIntegerFluidViscosity READ_INTEGER_FLUID_VISCOSITY = new AspectReadIntegerFluidViscosity();

    public static final AspectReadDoubleFluidFillRatio READ_DOUBLE_FLUID_FILLRATIO = new AspectReadDoubleFluidFillRatio();

    public static final AspectReadStringFluidName READ_STRING_FLUID_NAME = new AspectReadStringFluidName();
    public static final AspectReadStringFluidRarity READ_STRING_FLUID_RARITY = new AspectReadStringFluidRarity();

    public static final AspectReadObjectBlockFluid READ_BLOCK_FLUID_BLOCK = new AspectReadObjectBlockFluid();

    // --- Minecraft ---
    public static final AspectReadIntegerMinecraftRandom READ_INTEGER_MINECRAFT_RANDOM = new AspectReadIntegerMinecraftRandom();
    public static final AspectReadIntegerMinecraftPlayerCount READ_INTEGER_MINECRAFT_PLAYERCOUNT = new AspectReadIntegerMinecraftPlayerCount();
    public static final AspectReadIntegerMinecraftTicktime READ_INTEGER_MINECRAFT_TICKTIME = new AspectReadIntegerMinecraftTicktime();

    // --- Network ---
    public static final AspectReadBooleanNetworkApplicable READ_BOOLEAN_NETWORK_APPLICABLE = new AspectReadBooleanNetworkApplicable();

    public static final AspectReadIntegerNetworkElementCount READ_INTEGER_NETWORK_ELEMENT_COUNT = new AspectReadIntegerNetworkElementCount();
    public static final AspectReadIntegerNetworkEnergyBatteryCount READ_INTEGER_NETWORK_ENERGY_BATTERY_COUNT = new AspectReadIntegerNetworkEnergyBatteryCount();
    public static final AspectReadIntegerNetworkEnergyStored READ_INTEGER_NETWORK_ENERGY_STORED = new AspectReadIntegerNetworkEnergyStored();
    public static final AspectReadIntegerNetworkEnergyMax READ_INTEGER_NETWORK_ENERGY_MAX = new AspectReadIntegerNetworkEnergyMax();

    // --------------- Write ---------------
    public static final AspectWriteBooleanRedstone WRITE_BOOLEAN_REDSTONE = new AspectWriteBooleanRedstone();

    public static final AspectWriteIntegerRedstone WRITE_INTEGER_REDSTONE = new AspectWriteIntegerRedstone();

}


text:
#ifndef QUICKSTEP_UTILITY_PTR_VECTOR_HPP_
#define QUICKSTEP_UTILITY_PTR_VECTOR_HPP_

#include <iterator>
#include <vector>

#include "utility/Macros.hpp"

#include "glog/logging.h"

namespace quickstep {

/** \addtogroup Utility
 *  @{
 */

/**
 * @brief A vector of pointers to objects, which are automatically deleted when
 *        the PtrVector goes out of scope.
 **/
template <typename T, bool null_allowed = false>
class PtrVector {
 public:
  // TODO(chasseur): Attempt some template magic to get rid of the duplicated
  // code between iterator classes.

  /**
   * @brief Iterator over the contents of a PtrVector.
   * @warning If null_allowed is true, then always check that isNull() is false
   *          before attempting to dereference.
   **/
  class PtrVectorIterator : public std::iterator<std::random_access_iterator_tag, T> {
   public:
    typedef typename std::iterator<std::random_access_iterator_tag, T>::difference_type difference_type;

    PtrVectorIterator() {
    }

    PtrVectorIterator(const PtrVectorIterator& other)
        : internal_iterator_(other.internal_iterator_) {
    }

    PtrVectorIterator& operator=(const PtrVectorIterator& other) {
      if (this != &other) {
        internal_iterator_ = other.internal_iterator_;
      }
      return *this;
    }

    // Comparisons.
    inline bool operator==(const PtrVectorIterator& other) const {
      return internal_iterator_ == other.internal_iterator_;
    }

    inline bool operator!=(const PtrVectorIterator& other) const {
      return internal_iterator_ != other.internal_iterator_;
    }

    inline bool operator<(const PtrVectorIterator& other) const {
      return internal_iterator_ < other.internal_iterator_;
    }

    inline bool operator<=(const PtrVectorIterator& other) const {
      return internal_iterator_ <= other.internal_iterator_;
    }

    inline bool operator>(const PtrVectorIterator& other) const {
      return internal_iterator_ > other.internal_iterator_;
    }

    inline bool operator>=(const PtrVectorIterator& other) const {
      return internal_iterator_ >= other.internal_iterator_;
    }

    // Increment/decrement.
    inline PtrVectorIterator& operator++() {
      ++internal_iterator_;
      return *this;
    }

    PtrVectorIterator operator++(int) {
      PtrVectorIterator result(*this);
      ++(*this);
      return result;
    }

    inline PtrVectorIterator& operator--() {
      --internal_iterator_;
      return *this;
    }

    PtrVectorIterator operator--(int) {
      PtrVectorIterator result(*this);
      --(*this);
      return result;
    }

    // Compound assignment.
    inline PtrVectorIterator& operator+=(difference_type n) {
      internal_iterator_ += n;
      return *this;
    }

    inline PtrVectorIterator& operator-=(difference_type n) {
      internal_iterator_ -= n;
      return *this;
    }

    // Note: + operator with difference_type on the left is defined out-of-line.
    PtrVectorIterator operator+(difference_type n) const {
      return PtrVectorIterator(internal_iterator_ + n);
    }

    PtrVectorIterator operator-(difference_type n) const {
      return PtrVectorIterator(internal_iterator_ - n);
    }

    difference_type operator-(const PtrVectorIterator &other) const {
      return PtrVectorIterator(internal_iterator_ - other.internal_iterator_);
    }

    // Dereference.
    /**
     * @brief Check whether the element at the current iterator position is
     *        NULL.
     * @return Whether the element at the current iterator position is NULL.
     **/
    inline bool isNull() const {
      return (null_allowed && (*internal_iterator_ == nullptr));
    }

    /**
     * @brief Delete the element at the current iterator position and replace
     *        it with a new value.
     *
     * @param value_ptr The new value to place at the current position. The
     *        PtrVector takes ownership of the pointed-to value.
     **/
    void replaceValue(T *value_ptr) {
      if (!null_allowed) {
        DCHECK(value_ptr != nullptr);
      }
      if (!null_allowed || (*internal_iterator_ != nullptr)) {
        delete *internal_iterator_;
      }
      *internal_iterator_ = value_ptr;
    }

    /**
     * @brief Replace the element at the current iterator position, and
     *        release ownership and return the original value.
     *
     * @param value_ptr The new value to place at the current position. The
     *        PtrVector takes ownership of the pointed-to value.
     * @return A pointer to the original value at the current position. The
     *         PtrVector no longer owns the pointed-to object, which should now
     *         be managed by the caller.
     **/
    T* releaseAndReplaceElement(T *value_ptr) {
      if (!null_allowed) {
        DCHECK(value_ptr != nullptr);
      }
      T *original_value = *internal_iterator_;
      *internal_iterator_ = value_ptr;
      return original_value;
    }

    inline T& operator*() const {
      if (null_allowed) {
        DCHECK(!isNull());
      }
      return **internal_iterator_;
    }

    inline T* operator->() const {
      if (null_allowed) {
        DCHECK(!isNull());
      }
      return *internal_iterator_;
    }

    // Offset dereference. Potentially unsafe if null_allowed.
    T& operator[](difference_type n) const {
      if (null_allowed) {
        DCHECK(internal_iterator_[n] != nullptr);
      }
      return *(internal_iterator_[n]);
    }

   private:
    explicit PtrVectorIterator(const typename std::vector<T*>::iterator &internal_iterator)
        : internal_iterator_(internal_iterator) {
    }

    typename std::vector<T*>::iterator internal_iterator_;

    friend class PtrVector;
    friend class PtrVectorConstIterator;
  };

  /**
   * @brief Const iterator over the contents of a PtrVector.
   * @warning If null_allowed is true, then always check that isNull() is false
   *          before attempting to dereference.
   **/
  class PtrVectorConstIterator : public std::iterator<std::input_iterator_tag, const T> {
   public:
    typedef typename std::iterator<std::input_iterator_tag, T>::difference_type difference_type;

    PtrVectorConstIterator() {
    }

    PtrVectorConstIterator(const PtrVectorConstIterator& other)
        : internal_iterator_(other.internal_iterator_) {
    }

    PtrVectorConstIterator(const PtrVectorIterator& other)  // NOLINT(runtime/explicit) - allow implicit conversion
        : internal_iterator_(other.internal_iterator_) {
    }

    PtrVectorConstIterator& operator=(const PtrVectorConstIterator& other) {
      if (this != &other) {
        internal_iterator_ = other.internal_iterator_;
      }
      return *this;
    }

    PtrVectorConstIterator& operator=(const PtrVectorIterator& other) {
      internal_iterator_ = other.internal_iterator_;
      return *this;
    }

    // Comparisons.
    inline bool operator==(const PtrVectorConstIterator& other) const {
      return internal_iterator_ == other.internal_iterator_;
    }

    inline bool operator!=(const PtrVectorConstIterator& other) const {
      return internal_iterator_ != other.internal_iterator_;
    }

    inline bool operator<(const PtrVectorConstIterator& other) const {
      return internal_iterator_ < other.internal_iterator_;
    }

    inline bool operator<=(const PtrVectorConstIterator& other) const {
      return internal_iterator_ <= other.internal_iterator_;
    }

    inline bool operator>(const PtrVectorConstIterator& other) const {
      return internal_iterator_ > other.internal_iterator_;
    }

    inline bool operator>=(const PtrVectorConstIterator& other) const {
      return internal_iterator_ >= other.internal_iterator_;
    }

    // Increment/decrement.
    inline PtrVectorConstIterator& operator++() {
      ++internal_iterator_;
      return *this;
    }

    PtrVectorConstIterator operator++(int) {
      PtrVectorConstIterator result(*this);
      ++(*this);
      return result;
    }

    inline PtrVectorConstIterator& operator--() {
      --internal_iterator_;
      return *this;
    }

    PtrVectorConstIterator operator--(int) {
      PtrVectorConstIterator result(*this);
      --(*this);
      return result;
    }

    // Compound assignment.
    inline PtrVectorConstIterator& operator+=(difference_type n) {
      internal_iterator_ += n;
      return *this;
    }

    inline PtrVectorConstIterator& operator-=(difference_type n) {
      internal_iterator_ -= n;
      return *this;
    }

    // Note: + operator with difference_type on the left is defined out-of-line.
    PtrVectorConstIterator operator+(difference_type n) const {
      return PtrVectorConstIterator(internal_iterator_ + n);
    }

    PtrVectorConstIterator operator-(difference_type n) const {
      return PtrVectorConstIterator(internal_iterator_ - n);
    }

    difference_type operator-(const PtrVectorConstIterator &other) const {
      return PtrVectorConstIterator(internal_iterator_ - other.internal_iterator_);
    }

    // Dereference.
    /**
     * @brief Check whether the element at the current iterator position is
     *        NULL.
     * @return Whether the element at the current iterator position is NULL.
     **/
    inline bool isNull() const {
      return (null_allowed && (*internal_iterator_ == nullptr));
    }

    inline const T& operator*() const {
      if (null_allowed) {
        DCHECK(!isNull());
      }
      return **internal_iterator_;
    }

    inline const T* operator->() const {
      if (null_allowed) {
        DCHECK(!isNull());
      }
      return *internal_iterator_;
    }

    // Offset dereference. Potentially unsafe if null_allowed.
    const T& operator[](difference_type n) const {
      if (null_allowed) {
        DCHECK(internal_iterator_[n] != nullptr);
      }
      return *(internal_iterator_[n]);
    }

   private:
    explicit PtrVectorConstIterator(const typename std::vector<T*>::const_iterator &internal_iterator)
        : internal_iterator_(internal_iterator) {
    }

    typename std::vector<T*>::const_iterator internal_iterator_;

    friend class PtrVector;
  };

  /**
   * @brief Input iterator over the contents of a PtrVector which automatically
   *        skips over NULL entries.
   **/
  class PtrVectorConstSkipIterator : public std::iterator<std::input_iterator_tag, const T> {
   public:
    typedef typename std::iterator<std::input_iterator_tag, T>::difference_type difference_type;

    PtrVectorConstSkipIterator()
        : parent_vector_(nullptr) {
    }

    PtrVectorConstSkipIterator(const PtrVectorConstSkipIterator& other)
        : internal_iterator_(other.internal_iterator_),
          parent_vector_(other.parent_vector_) {
    }

    PtrVectorConstSkipIterator& operator=(const PtrVectorConstSkipIterator& other) {
      if (this != &other) {
        internal_iterator_ = other.internal_iterator_;
        parent_vector_ = other.parent_vector_;
      }
      return *this;
    }

    // Comparisons.
    inline bool operator==(const PtrVectorConstSkipIterator& other) const {
      return internal_iterator_ == other.internal_iterator_;
    }

    inline bool operator!=(const PtrVectorConstSkipIterator& other) const {
      return internal_iterator_ != other.internal_iterator_;
    }

    inline bool operator<(const PtrVectorConstSkipIterator& other) const {
      return internal_iterator_ < other.internal_iterator_;
    }

    inline bool operator<=(const PtrVectorConstSkipIterator& other) const {
      return internal_iterator_ <= other.internal_iterator_;
    }

    inline bool operator>(const PtrVectorConstSkipIterator& other) const {
      return internal_iterator_ > other.internal_iterator_;
    }

    inline bool operator>=(const PtrVectorConstSkipIterator& other) const {
      return internal_iterator_ >= other.internal_iterator_;
    }

    // Increment/decrement.
    inline PtrVectorConstSkipIterator& operator++() {
      ++internal_iterator_;
      DCHECK(parent_vector_ != nullptr);
      while (internal_iterator_ != parent_vector_->end()) {
        if (*internal_iterator_ != nullptr) {
          break;
        }
        ++internal_iterator_;
      }
      return *this;
    }

    PtrVectorConstSkipIterator operator++(int) {
      PtrVectorConstSkipIterator result(*this);
      ++(*this);
      return result;
    }

    inline const T& operator*() const {
      return **internal_iterator_;
    }

    inline const T* operator->() const {
      return *internal_iterator_;
    }

   private:
    explicit PtrVectorConstSkipIterator(const typename std::vector<T*>::const_iterator &internal_iterator,
                                        const std::vector<T*> *parent_vector)
        : internal_iterator_(internal_iterator), parent_vector_(parent_vector) {
      DCHECK(parent_vector_ != nullptr);
      while ((internal_iterator_ != parent_vector_->end()) && (*internal_iterator_ == nullptr)) {
        ++internal_iterator_;
      }
    }

    typename std::vector<T*>::const_iterator internal_iterator_;
    const std::vector<T*> *parent_vector_;

    friend class PtrVector;
  };

  typedef typename std::vector<T*>::size_type size_type;
  typedef T value_type;
  typedef PtrVectorIterator iterator;
  typedef PtrVectorConstIterator const_iterator;
  typedef PtrVectorConstSkipIterator const_skip_iterator;

  PtrVector() {
  }

  ~PtrVector() {
    for (typename std::vector<T*>::iterator it = internal_vector_.begin();
         it != internal_vector_.end();
         ++it) {
      if (!null_allowed || (*it != nullptr)) {
        delete *it;
      }
    }
  }

  inline size_type size() const {
    return internal_vector_.size();
  }

  inline size_type max_size() const {
    return internal_vector_.max_size();
  }

  inline size_type capacity() const {
    return internal_vector_.capacity();
  }

  inline bool empty() const {
    return internal_vector_.empty();
  }

  /**
   * @brief Check whether this vector contains any actual objects. Unlike
   *        empty(), this returns true if the vector has some elements, but
   *        they are all NULL.
   *
   * @return Whether this PtrVector is empty of actual objects.
   **/
  bool emptyNullCheck() const {
    if (null_allowed) {
      for (typename std::vector<T*>::const_iterator it = internal_vector_.begin();
           it != internal_vector_.end();
           ++it) {
        if (*it != nullptr) {
          return false;
        }
      }
      return true;
    } else {
      return empty();
    }
  }

  inline void reserve(size_type n) {
    internal_vector_.reserve(n);
  }

  // Iterators
  iterator begin() {
    return iterator(internal_vector_.begin());
  }

  iterator end() {
    return iterator(internal_vector_.end());
  }

  const_iterator begin() const {
    return const_iterator(internal_vector_.begin());
  }

  const_iterator end() const {
    return const_iterator(internal_vector_.end());
  }

  /**
   * @brief Get an iterator at the beginning of this PtrVector which
   *        automatically skips over NULL entries.
   *
   * @return An iterator at the beginning of this PtrVector which automatically
   *         skips over NULL entries.
   **/
  const_skip_iterator begin_skip() const {
    return const_skip_iterator(internal_vector_.begin(), &internal_vector_);
  }

  /**
   * @brief Get an iterator at one past the end of this PtrVector which
   *        automatically skips over NULL entries.
   *
   * @return An iterator at one past the end of this PtrVector which
   *         automatically skips over NULL entries.
   **/
  const_skip_iterator end_skip() const {
    return const_skip_iterator(internal_vector_.end(), &internal_vector_);
  }

  /**
   * @brief Check whether the element at the specified position is NULL.
   *
   * @param n The position in this PtrVector to check.
   * @return Whether the element at position n is NULL.
   **/
  inline bool elementIsNull(const size_type n) const {
    if (null_allowed && (internal_vector_[n] == nullptr)) {
      return true;
    } else {
      return false;
    }
  }

  /**
   * @brief Check whether the element at the specified position is NULL.
   * @note This is similar to elementIsNull(), but uses std::vector::at(),
   *       which throws std::out_of_range exceptions.
   *
   * @param n The position in this PtrVector to check.
   * @return Whether the element at position n is NULL.
   **/
  inline bool elementIsNullAt(const size_type n) const {
    if (null_allowed && (internal_vector_.at(n) == nullptr)) {
      return true;
    } else {
      return false;
    }
  }

  inline T& front() {
    if (null_allowed) {
      typename std::vector<T*>::iterator it = internal_vector_.begin();
      while ((it != internal_vector_.end()) && (*it == nullptr)) {
        ++it;
      }
      return **it;
    } else {
      return *(internal_vector_.front());
    }
  }

  inline const T& front() const {
    if (null_allowed) {
      typename std::vector<T*>::const_iterator it = internal_vector_.begin();
      while ((it != internal_vector_.end()) && (*it == nullptr)) {
        ++it;
      }
      return **it;
    } else {
      return *(internal_vector_.front());
    }
  }

  inline T& back() {
    if (null_allowed) {
      typename std::vector<T*>::reverse_iterator it = internal_vector_.rbegin();
      while ((it != internal_vector_.rend()) && (*it == nullptr)) {
        ++it;
      }
      return **it;
    } else {
      return *(internal_vector_.back());
    }
  }

  inline const T& back() const {
    if (null_allowed) {
      typename std::vector<T*>::const_reverse_iterator it = internal_vector_.rbegin();
      while ((it != internal_vector_.rend()) && (*it == nullptr)) {
        ++it;
      }
      return **it;
    } else {
      return *(internal_vector_.back());
    }
  }

  inline T& operator[](const size_type n) {
    if (null_allowed) {
      DCHECK(!elementIsNull(n));
    }
    return *(internal_vector_[n]);
  }

  inline const T& operator[](const size_type n) const {
    if (null_allowed) {
      DCHECK(!elementIsNull(n));
    }
    return *(internal_vector_[n]);
  }

  inline T& at(const size_type n) {
    if (null_allowed) {
      DCHECK(!elementIsNullAt(n));
    }
    return *(internal_vector_.at(n));
  }

  inline const T& at(const size_type n) const {
    if (null_allowed) {
      DCHECK(!elementIsNullAt(n));
    }
    return *(internal_vector_.at(n));
  }

  inline void push_back(T *value_ptr) {
    if (!null_allowed) {
      DCHECK(value_ptr != nullptr);
    }
    internal_vector_.push_back(value_ptr);
  }

  /**
   * @brief Delete an element at the specified index and replace it with a new
   *        value.
   *
   * @param n The position of the element to replace.
   * @param value_ptr The new value to place at position n. This PtrVector
   *        takes ownership of the pointed-to value.
   **/
  void replaceElement(const size_type n, T *value_ptr) {
    if (!null_allowed) {
      DCHECK(value_ptr != nullptr);
    }
    if (!null_allowed || (internal_vector_[n] != nullptr)) {
      delete internal_vector_[n];
    }
    internal_vector_[n] = value_ptr;
  }

  /**
   * @brief Replace an element at the specified index with a new value, and
   *        release ownership and return the original value.
   *
   * @param n The position of the element to replace.
   * @param value_ptr The new value to place at position n. This PtrVector
   *        takes ownership of the pointed-to value.
   * @return A pointer to the original value at position n. This PtrVector no
   *         longer owns the pointed-to object, which should now be managed
   *         by the caller.
   **/
  T* releaseAndReplaceElement(const size_type n, T *value_ptr) {
    if (!null_allowed) {
      DCHECK(value_ptr != nullptr);
    }
    T *original_value = internal_vector_[n];
    internal_vector_[n] = value_ptr;
    return original_value;
  }

  /**
   * @brief Delete an element and set it to null. Only usable if null_allowed
   *        is true.
   *
   * @param n The position of the element to delete.
   **/
  void deleteElement(const size_type n) {
    DCHECK(null_allowed);
    if (internal_vector_[n] != nullptr) {
      delete internal_vector_[n];
      internal_vector_[n] = nullptr;
    }
  }

  /**
   * @brief Delete the last element and truncate the vector. Only usable if
   *        null_allowed is false.
   **/
  void removeBack() {
    DCHECK(!null_allowed);
    DCHECK(!internal_vector_.empty());
    delete internal_vector_.back();
    internal_vector_.resize(internal_vector_.size() - 1);
  }

  /**
   * @brief Get a const reference to the internal vector of pointers.
   *
   * @return A const reference to the internal vector of pointers.
   **/
  const std::vector<T*>& getInternalVector() const {
    return internal_vector_;
  }

  /**
   * @brief Get a mutable pointer to the internal vector of pointers.
   * @warning Only call this if you really know what you are doing.
   *
   * @return A mutable pointer to the internal vector of pointers.
   **/
  std::vector<T*>* getInternalVectorMutable() {
    return &internal_vector_;
  }

 private:
  std::vector<T*> internal_vector_;

  DISALLOW_COPY_AND_ASSIGN(PtrVector);
};

template <typename T>
typename PtrVector<T>::PtrVectorIterator operator+(
    const typename PtrVector<T>::PtrVectorIterator::difference_type n,
    const typename PtrVector<T>::PtrVectorIterator &it) {
  return it + n;
}

/** @} */

}  // namespace quickstep

#endif  // QUICKSTEP_UTILITY_PTR_VECTOR_HPP_