anchor.diff:              this.incidentMessageScope = MessageScope.Local.of(() -> this.edgeTraversal.get().clone());
               this.countMessageScope = MessageScope.Local.of(new MessageScope.Local.ReverseTraversalSupplier(this.incidentMessageScope));
           }
  -        this.vertexCountAsDouble = configuration.getDouble(VERTEX_COUNT, 1.0d);
  -        this.alpha = configuration.getDouble(ALPHA, 0.85d);
  -        this.totalIterations = configuration.getInt(TOTAL_ITERATIONS, 30);
  +        this.alpha = configuration.getDouble(ALPHA, this.alpha);
  +        this.epsilon = configuration.getDouble(EPSILON, this.epsilon);
  +        this.maxIterations = configuration.getInt(MAX_ITERATIONS, 20);
           this.property = configuration.getString(PROPERTY, PAGE_RANK);
  -        this.vertexComputeKeys = new HashSet<>(Arrays.asList(VertexComputeKey.of(this.property, false), VertexComputeKey.of(EDGE_COUNT, true))); <5>
  +        this.vertexComputeKeys = new HashSet<>(Arrays.asList(
  +                VertexComputeKey.of(this.property, false),
  +                VertexComputeKey.of(EDGE_COUNT, true))); <5>
  +        this.memoryComputeKeys = new HashSet<>(Arrays.asList(
  +                MemoryComputeKey.of(TELEPORTATION_ENERGY, Operator.sum, true, true),
  +                MemoryComputeKey.of(VERTEX_COUNT, Operator.sum, true, true),
  +                MemoryComputeKey.of(CONVERGENCE_ERROR, Operator.sum, false, true)));
       }
   
       @Override
       public void storeState(final Configuration configuration) {
           VertexProgram.super.storeState(configuration);
  -        configuration.setProperty(VERTEX_COUNT, this.vertexCountAsDouble);
           configuration.setProperty(ALPHA, this.alpha);
  -        configuration.setProperty(TOTAL_ITERATIONS, this.totalIterations);
  +        configuration.setProperty(EPSILON, this.epsilon);
           configuration.setProperty(PROPERTY, this.property);
  +        configuration.setProperty(MAX_ITERATIONS, this.maxIterations);
           if (null != this.edgeTraversal)
               this.edgeTraversal.storeState(configuration, EDGE_TRAVERSAL);
           if (null != this.initialRankTraversal)
  
positive.code: 
      @Override
      public void setup(final Memory memory) {
  
      }
  
      @Override
      public void execute(final Vertex vertex, Messenger<Double> messenger, final Memory memory) { <7>
          if (memory.isInitialIteration()) {
              messenger.sendMessage(this.countMessageScope, 1.0d); <8>
          } else if (1 == memory.getIteration()) {
              double initialPageRank = (null == this.initialRankTraversal ?
                      1.0d :
                      TraversalUtil.apply(vertex, this.initialRankTraversal.get()).doubleValue()) / this.vertexCountAsDouble;  <9>
              double edgeCount = IteratorUtils.reduce(messenger.receiveMessages(), 0.0d, (a, b) -> a + b);
              vertex.property(VertexProperty.Cardinality.single, this.property, initialPageRank);
              vertex.property(VertexProperty.Cardinality.single, EDGE_COUNT, edgeCount);
              if (!this.terminate(memory)) // don't send messages if this is the last iteration
                  messenger.sendMessage(this.incidentMessageScope, initialPageRank / edgeCount);
          } else {
              double newPageRank = IteratorUtils.reduce(messenger.receiveMessages(), 0.0d, (a, b) -> a + b); <10>
              newPageRank = (this.alpha * newPageRank) + ((1.0d - this.alpha) / this.vertexCountAsDouble);
              vertex.property(VertexProperty.Cardinality.single, this.property, newPageRank);
              if (!this.terminate(memory)) // don't send messages if this is the last iteration
                  messenger.sendMessage(this.incidentMessageScope, newPageRank / vertex.<Double>value(EDGE_COUNT));
          }
      }
  
      @Override
      public boolean terminate(final Memory memory) {
          return memory.getIteration() >= this.totalIterations;  <11>
      }
  
      @Override
      public String toString() {
          return StringFactory.vertexProgramString(this, "alpha=" + this.alpha + ", iterations=" + this.totalIterations);
      }
  }
  ----
  
negative.code: <8> In order to determine how to distribute the energy to neighbors, a "1"-count is used to determine how many incident vertices exist for the `MessageScope`.
  <9> Initially, each vertex is provided an equal amount of energy represented as a double.
  <10> Energy is aggregated, computed on according to the PageRank algorithm, and then disseminated according to the defined `MessageScope.Local`.
  <11> The computation is terminated after epsilon-convergence is met or a pre-defined number of iterations have taken place.
  
  The above `PageRankVertexProgram` is used as follows.
  
  