Updated Search.java documentation (#184)
authorYahya <yahya.ismail@hotmail.ca>
Sun, 31 Mar 2019 11:54:16 +0000 (07:54 -0400)
committercyrille-artho <cyrille-artho@users.noreply.github.com>
Sun, 31 Mar 2019 11:54:16 +0000 (13:54 +0200)
* Updated Search.java documentation

Fixed spelling and grammar errors, added verbosity to existing javadoc
and added javadoc where none previously existed.

Surrounded some previously uncaught methods and variables with {@code }

src/main/gov/nasa/jpf/search/Search.java

index e447741a3c50e736474bb424f2d478b452cb658c..01fdb0b2da3f165efe2cd1e9773309cbd57b41aa 100644 (file)
@@ -39,50 +39,113 @@ import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
- * the mother of all search classes. Mostly takes care of listeners, keeping
- * track of state attributes and errors. This class mainly keeps the
- * general search info like depth, configured properties etc.
+ * The {@code Search} abstract class is at the heart of all search classes. Even when it is not extended by child classes, it will
+ * be embedded in the logic as an input for some of the methods. 
+ * 
+ * <p>The main purpose of the {@code Search} class is to track general search information such as depth, configured properties, 
+ * errors, etc. as well as to define how the search algorithm functions. In its simplest form, a search algorithm can be defined 
+ * using the abstract method {@code search} with a series of {@code forward} and {@code backtrack}. More complex search 
+ * algorithms can also make use of the state storing functionality of the {@code Search} class, as well as ignoring states and
+ * removing states from the search tree.
+ * 
+ * <p>Another very important aspect of the {@code Search} class is not only to implement search algorithms, but also to define
+ * the information that describes the current search loop. This is crucial in order to enable the {@code SearchListener} and 
+ * {@code SearchListenerAdapter} classes responsible for extracting crucial data from the search loop during its verification
+ * efforts.
  */
 public abstract class Search {
   
+  /** The {@code JPFLogger} object assigned to the {@code gov.nasa.jpf.search} subsystem 
+   * @see gov.nasa.jpf.util.JPFLogger
+   */
   protected static JPFLogger log = JPF.getLogger("gov.nasa.jpf.search");
   
-  /** error encountered during last transition, null otherwise */
+  /** The value of {@code currentError} will either be the error encountered during last
+   *  transition or null if no error was encountered */
   protected Error currentError = null;
+  
+  /** A running list of all errors encountered during verification. The list will always 
+   * contain the current and past values of {@code currentError}. Errors are set added
+   * during verification in the {@code error}
+   * method.
+   * 
+   * <p>{@code errors} will only hold one error before verification stops unless {@code getAllErrors}
+   * is set to true
+   * 
+   * @see #error(Property, Path, ThreadList)
+   * @see #getAllErrors
+   */
   protected ArrayList<Error> errors = new ArrayList<Error>();
 
-  protected int       depth = 0;
-  protected VM       vm;
+  /**  {@code depth} represents the current depth of the search tree. */
+  protected int depth = 0;
+  /** {@code vm} represents the virtual machine that the search algorithm will be traversing*/
+  protected VM vm;
 
+  /** A list of properties provided from the search configuration at the start of verification. Every property has a {@code check}
+   * method that will be used during verification to tell if any of the properties have been violated.*/
   protected ArrayList<Property> properties;
 
+  /** A property set by the user before verification. If {@code matchDepth} is true it will change the behavior of 
+   * {@code isNewState()}.
+   * @see #isNewState() */
   protected boolean matchDepth;
+  /** A property set by the user to define what the minimum memory required to keep verifying is. The reason this is a non-zero
+   * value is to ensure some memory is left over to output a legible message before ending execution instead of simply throwing
+   * an {@code OutOfMemoryError}.
+   * 
+   * <p> The default value for {@code minFreeMemory} is 1024 << 10 bytes. */
   protected long    minFreeMemory;
+  /** A property set by the user to define what the maximum depth allowed during verification is. 
+   * 
+   * <p>By default the value is set to {@code Integer.MAX_VALUE}*/
   protected int     depthLimit;
+  
+  /** A property set by the user to define whether to halt execution after encountering the first error during verification.
+   * If {@code getAllErrors} is set to true, verification will not stop after the first error, and every possible error
+   * during verification will be logged as a result. */
   protected boolean getAllErrors;
 
-  // message explaining the last search constraint hit
+  /** A {@code String} set to contain details on what the constraint that caused verification to halt was. Will generally be 
+   * used by the {@code searchContraintHit} methods in {@code SearchListeners}.
+   * 
+   * @see gov.nasa.jpf.search.SearchListener#searchConstraintHit(Search) */
   protected String lastSearchConstraint;
 
-  // these states control the search loop
+  /** {@code done} is a flag set during verification to notify the search loop when verification has finished. */
   protected boolean done = false;
+  /** {@code doBacktrack} is a flag set during verification in order to request that the search loop backtracks
+   * one state.*/
   protected boolean doBacktrack = false;
 
-  // do we have a probe request
+ /** {@code notifyProbeListeners} is a flag set during verification stating whether or not a probe has been 
+  * requested. When a probe is requested, relevant {@code SearchListeners} will be notified via {@code checkAndResetProbeRequest}*/
   protected AtomicBoolean notifyProbeListeners = new AtomicBoolean(false);
 
-  /** search listeners. We keep them in a simple array to avoid
+  /** {@code listeners} is an array used to hold {@code SearchListener} objects. We keep them in a simple array to avoid
    creating objects on each notification */
   protected SearchListener[] listeners = new SearchListener[0];
 
-  /** this is a special SearchListener that is always notified last, so that
-   * PublisherExtensions can be sure the notification has been processed by all listeners */
+  /** {@code reporter} is a special listener that is always notified last in order to ensure all other listeners have been notified
+   * beforehand. {@code reporter} is used to report information about the search loop to whichever output method the user has 
+   * specified.
+   * 
+   *  <p>By default, the output method is to console.*/
   protected Reporter reporter;
 
-  protected final Config config; // to later-on access settings that are only used once (not ideal)
+  /** {@code config} is an object passed in during instantiation of the {@code Search} object and it specifies the properties and 
+   * configurations the search loop should run under. The value behind {@code config} is only ever used once and stored within this
+   * object.*/
+  protected final Config config;
 
-  // don't forget to unregister or we have a HUGE memory leak if the same Config object is
-  // reused for several JPF runs
+  /**
+   * {@code ConfigListener} is an implementation of the interface {@code ConfigChangeListener} and is used to subscribe to changes 
+   * that occur to the configuration of JPF in order to update the {@code config} object. While highly useful, one should always
+   * remember to unregister the {@code config} object from each {@code ConfigListener} once it is no longer needed. Failure to
+   * do this will cause massive memory leaks to begin piling up as a result of the same {@code Config} object being used across
+   * several JPF executions. 
+   *
+   */
   class ConfigListener implements ConfigChangeListener {
 
     @Override
@@ -109,9 +172,19 @@ public abstract class Search {
     }
   }
   
-  /** storage to keep track of state depths */
+  /** {@code stateDepth} is an int vector storage system (akin to a map) that is responsible for associating states with their 
+   * corresponding depths. 
+   * 
+   * <p>{@code stateDepth} maps the state id of every state to the corresponding depth, in a one to one mapping.*/
   protected final IntVector stateDepth = new IntVector();
 
+  /** 
+   * Constructs a {@code Search} object using the configuration specified by the user in {@code config} and a virtual machine
+   * that will be used for verification.
+   * 
+   *  @param config The configuration and properties that the search loop will be required to commence verification under
+   *  @param vm The virtual machine that the search loop will traverse and verify states from
+   */
   protected Search (Config config, VM vm) {
     this.vm = vm;
     this.config = config;
@@ -126,6 +199,12 @@ public abstract class Search {
     config.addChangeListener( new ConfigListener());
   }
 
+  /**
+   * Initializes the properties that the search loop will need to run under in order to make sure that each iteration of the search
+   * loop is in compliance with the properties set by JPF and the user.
+   * 
+   * @param conf The configuration object ({@code config}) that contains the necessary information to initialize the property values
+   */
   protected void initialize( Config conf){
     depthLimit = conf.getInt("search.depth_limit", Integer.MAX_VALUE);
     matchDepth = conf.getBoolean("search.match_depth");
@@ -134,53 +213,103 @@ public abstract class Search {
   }
   
   /**
-   * called after the JPF run is finished. Shouldn't be public, but is called by JPF
+   * Called after the JPF run is finished. Should not be public, but is called by JPF
    */
   public void cleanUp(){
     // nothing here, the ConfigListener removes itself
   }
   
+  /** 
+   * Returns the {@code config} object that is used by the {@code Search} class.
+   * 
+   * @return The configuration object that is used for verification
+   */
   public Config getConfig() {
     return config;
   }
   
+  /**
+   * One of the most important methods in the {@code Search} class. {@code search} is used to specify what the algorithm and behavior 
+   * for verification are. When the term "search loop" is brought up in other documentation, it generally means the loop that is used
+   * running in the {@code search} method.
+   */
   public abstract void search ();
 
+  /**
+   * Sets the {@code reporter} object used during verification to the specified {@code reporter}.
+   * 
+   * @param reporter The reporter used to replace the current reporter object in the {@code Search} class
+   */
   public void setReporter(Reporter reporter){
     this.reporter = reporter;
   }
 
+  /**
+   * Appends a {@code SearchListener} object to the {@code listener} array. In addition to appending the search listener, the action is also logged
+   * to the JPFLog {@code log} used in the {@code Search} class.
+   * 
+   * @param newListener A new {@code SearchListener} to append to the {@code listener} array
+   */
   public void addListener (SearchListener newListener) {
     log.info("SearchListener added: ", newListener);
     listeners = Misc.appendElement(listeners, newListener);
   }
 
+  /**
+   * Checks whether a listener of the same type as {@code listenerCls} exists in {@code listeners} already.
+   * 
+   * @param listenerCls The object type to check {@code listeners} against
+   * @return true if an element of the same type as the input parameter exists in {@code listeners}. False otherwise
+   */
   public boolean hasListenerOfType (Class<?> listenerCls) {
     return Misc.hasElementOfType(listeners, listenerCls);
   }
   
+  /**
+   * Returns the next element in {@code listeners} after the element matching {@code prev} that is of the same type as {@code type}.
+   * 
+   * @param type The type of element to search for and return
+   * @param prev The previous element to begin the search from
+   * @return An element of the same class as {@code type} and coming after {@code prev} in the {@code listeners} array
+   */
   public <T> T getNextListenerOfType(Class<T> type, T prev){
     return Misc.getNextElementOfType(listeners, type, prev);
   }
 
-
+  /**
+   * Remove the specified {@code SearchListener} from the {@code listeners} array.
+   * 
+   * @param removeListener The element to remove from the {@code listeners} array
+   */
   public void removeListener (SearchListener removeListener) {
     listeners = Misc.removeElement(listeners, removeListener);
   }
 
-
+  /**
+   * Add a new property to {@code properties}
+   * 
+   * @param newProperty The property to add to {@code properties}
+   */
   public void addProperty (Property newProperty) {
     properties.add(newProperty);
   }
 
+  /**
+   * Remove the specified property from {@code properties}
+   * 
+   * @param oldProperty The property to remove from {@code properties}
+   */
   public void removeProperty (Property oldProperty) {
      properties.remove(oldProperty);
   }
 
   /**
-   * return set of configured properties
-   * note there is a name clash here - JPF 'properties' have nothing to do with
-   * Java properties (java.util.Properties)
+   * Returns the list of configured properties.
+   * 
+   * <p>Note there is a name clash here - JPF 'properties' have nothing to do with Java properties (java.util.Properties)
+   * 
+   * @param config The config object to retrieve the properties list from
+   * @return The list of configured properties
    */
   protected ArrayList<Property> getProperties (Config config) {
     Class<?>[] argTypes = { Config.class, Search.class };
@@ -192,7 +321,12 @@ public abstract class Search {
     return list;
   }
 
-  // check for property violation, return true if not done
+  /**
+   * Check for property violations and return true if a property is violated and the search loop has finished running (i.e. {@code done} 
+   * is set to true). Returns false otherwise.
+   * 
+   * @return true if an a property has been violated (i.e. {@code currentError} is not null) and {@code done} is true
+   */
   protected boolean hasPropertyTermination () {
     if (currentError != null){
       if (done){
@@ -205,7 +339,12 @@ public abstract class Search {
     return false;
   }
 
-  // this should only be called once per transition, otherwise it keeps adding the same error
+  /**
+   * Iterates through {@code properties} and checks for property violations. {@code checkPropertyViolation} should only be 
+   * called once per transition to avoid it adding the same error every time it is called.
+   * 
+   * @return true if a property violation is found, false otherwise
+   */
   protected boolean checkPropertyViolation () {
     for (Property p : properties) {
       if (!p.check(this, vm)) {
@@ -217,24 +356,39 @@ public abstract class Search {
     return false;
   }
 
+  /**
+   * Returns the list of errors encountered during verification
+   * 
+   * @return The list of errors encountered during verification
+   */
   public List<Error> getErrors () {
     return errors;
   }
 
+  /**
+   * Returns the number of errors encountered during verification. Will always return 1 if {@code getAllErrors} is false
+   * 
+   * @return The number of errors encountered during verification
+   */
   public int getNumberOfErrors(){
     return errors.size();
   }
 
+  /**
+   * Returns the search constraint that was most recently encountered
+   * 
+   * @return A String detailing the search constraint most recently hit or null if none was encountered
+   */
   public String getLastSearchConstraint() {
     return lastSearchConstraint;
   }
 
   /**
-   * request a probe
+   * Request a probe
    * 
-   * This does not do the actual listener notification, it only stores
+   * <p>This does not perform the actual listener notification, it only stores
    * the request, which is then processed from within JPFs inner execution loop.
-   * As a consequence, probeSearch() can be called async, and searchProbed() listeners
+   * As a consequence, {@code probeSearch} can be called asynchronously, and {@code searchProbed} listeners
    * don't have to bother with synchronization or inconsistent JPF states (notification 
    * happens from within JPFs main thread after a completed Instruction execution)
    */
@@ -243,8 +397,7 @@ public abstract class Search {
   }
   
   /**
-   * this does the actual notification and resets the request, hence this call
-   * should only happen from within JPFs main thread
+   * Performs the actual notification and resets the request, hence this call should only happen from within JPFs main thread
    */
   public void checkAndResetProbeRequest(){
     if (notifyProbeListeners.compareAndSet(true, false)){
@@ -253,12 +406,19 @@ public abstract class Search {
   }
   
   /**
-   * @return error encountered during *last* transition (null otherwise)
+   * Returns the most recent error encountered during the last transition
+   * 
+   * @return The error encountered during the last transition or null if none was encountered
    */
   public Error getCurrentError(){
     return currentError;
   }
 
+  /**
+   * Returns the most recent error encountered in the past
+   * 
+   * @return The most recent error encountered in the past or none if no error has been encountered during verification
+   */
   public Error getLastError() {
     int i=errors.size()-1;
     if (i >=0) {
@@ -268,30 +428,69 @@ public abstract class Search {
     }
   }
 
+  /**
+   * Returns whether or not the search loop has encountered an error yet
+   * 
+   * @return true if an error has been encountered, false otherwise
+   */
   public boolean hasErrors(){
     return !errors.isEmpty();
   }
 
+  /**
+   * Returns the {@code vm} object used by the search loop
+   * 
+   * @return the {@code vm} object used by {@code Search}
+   */
   public VM getVM() {
     return vm;
   }
 
+  /**
+   * Returns true if the search loop has transitioned into an end state in the virtual machine
+   * 
+   * @return true if the current state of the {@code vm} is an end state
+   */
   public boolean isEndState () {
     return vm.isEndState();
   }
 
+  /**
+   * Returns if an error has been encountered during the transition into the current state
+   * 
+   * @return true if an error has been encountered during the most recent transition, false otherwise
+   */
   public boolean isErrorState(){
     return (currentError != null);
   }
 
+  /**
+   * Returns whether of not the current state is an end state in the virtual machine
+   * 
+   * @return true if this is not an end state of the {@code vm}, false otherwise
+   */
   public boolean hasNextState () {
     return !isEndState();
   }
 
+  /**
+   * Returns whether a transition has occurred from the previous state or not
+   * 
+   * @return true if a transition has occurred, false otherwise
+   */
   public boolean transitionOccurred(){
     return vm.transitionOccurred();
   }
 
+  /**
+   * Returns whether the current state in the search loop is a new state and false otherwise. 
+   * 
+   * <p>However, if {@code matchDepth} is set to true,
+   * then it  will true if the state is new or if the states depth is less than the previously recorded depth. If the state is new, the states
+   * depth will also be recorded for future use.
+   * 
+   * @return true if the current state is a new state and false otherwise (behaviour changes if {@code matchDepth} is true
+   */
   public boolean isNewState () {
     boolean isNew = vm.isNewState();
 
@@ -308,53 +507,111 @@ public abstract class Search {
     return isNew;
   }
 
+  /**
+   * Returns whether the current state has been visited yet. The opposite of {@code isNewState}
+   * 
+   * @return true if the state has been visited, false otherwise (behavior changes if {@code matchDepth} is true)
+   * @see #isNewState()
+   */
   public boolean isVisitedState () {
     return !isNewState();
   }
 
+  /**
+   * Returns whether the current state is an ignored state in the virtual machine
+   * 
+   * @return true if the current state is an ignored state, false otherwise
+   */
   public boolean isIgnoredState(){
     return vm.isIgnoredState();
   }
 
+  /**
+   * Returns whether the current state has been fully explored by the search loop.
+   * 
+   * @return true if the current state has been fully explored and processed, false otherwise
+   */
   public boolean isProcessedState(){
     return vm.getChoiceGenerator().isProcessed();
   }
 
+  /**
+   * Return whether the search loop has finished verification
+   * 
+   * @return true if the search loop has finished verification, false otherwise
+   */
   public boolean isDone(){
     return done;
   }
 
+  /**
+   * Return the current depth of the search loop
+   * 
+   * @return The current depth inside the search tree.
+   */
   public int getDepth () {
     return depth;
   }
 
+  /**
+   * Returns the most recent search constraint that was encountered
+   * 
+   * @return A String detailing the most recent search constraint that was encountered
+   */
   public String getSearchConstraint () {
     return lastSearchConstraint;
   }
 
+  /**
+   * Returns the most recent transition that has occurred
+   * 
+   * @return The last transition that occurred during verification, or null if none has occurred
+   */
   public Transition getTransition () {
     return vm.getLastTransition();
   }
 
+  /**
+   * Returns the state id of the current state
+   * 
+   * @return The state id of the current state
+   */
   public int getStateId () {
     return vm.getStateId();
   }
 
+  /**
+   * Returns the purged states id
+   * 
+   * <p>Note that while it should return the purged states id, it currently only returns -1 as a 
+   * result of many searches not utilizing this functionality. If it is required, {@code getPurgedStateId}
+   * should be overridden and changed in subsequent child classes.
+   * 
+   * @return The purged states id (currently only returns -1)
+   */
   public int getPurgedStateId () {
     return -1; // a lot of Searches don't purge any states
   }
 
 
   /**
-   * this is somewhat redundant to SystemState.setIgnored(), but we don't
+   * Requests that the search loop backtracks one step
+   * 
+   * <p>This is somewhat redundant to {@code SystemState.setIgnored}, but we don't
    * want to mix the case of overriding state matching with backtracking when
-   * searching for multiple errors
+   * searching for multiple errors.
+   * 
+   * @return The value of {@code doBacktrack} after is has been set to true (i.e. always true)
    */
   public boolean requestBacktrack () {
     return doBacktrack = true;
   }
 
-
+  /**
+   * Returns the value of {@code doBacktrack} as well as resetting {@code doBacktrack} to false
+   * 
+   * @return the value of {@code doBackTrack}
+   */
   protected boolean checkAndResetBacktrackRequest() {
     if (doBacktrack){
       doBacktrack = false;
@@ -364,32 +621,82 @@ public abstract class Search {
     }
   }
 
+  /**
+   * Returns whether the search algorithm supports backtracking or not
+   * 
+   * @return true if the search algorithm supports backtracking, false otherwise (by default the return
+   * is true unless overridden)
+   */
   public boolean supportsBacktrack () {
     return true;
   }
 
+  /**
+   * Returns whether the search algorithm supports restoring states that have been stored (a useful method in 
+   * BreadthFirstSearch)
+   * 
+   * @return true if the search algorithm supports restoring states, false otherwise (by default the return
+   * is false as the function is unsupported)
+   */
   public boolean supportsRestoreState () {
     // not supported by default
     return false;
   }
 
+  /**
+   * Returns the depth limit set at the beginning of verification
+   * 
+   * @return The {@code depthLimit} property
+   */
   public int getDepthLimit () {
     return depthLimit;
   }
   
+  /**
+   * Sets a new value for the {@code depthLimit} property
+   * 
+   * @param limit The new limit to set {@code depthLimit} to
+   */
   public void setDepthLimit(int limit){
     depthLimit = limit;
   }
 
+  /**
+   * Returns a {@code SearchState} object with information describing the current state in the search loop
+   * 
+   * @return A {@code SearchState} object with information about the current state
+   */
   protected SearchState getSearchState () {
     return new SearchState(this);
   }
 
-  // can be used by SearchListeners to create path-less errors (liveness)
+  /**
+   * Creates a new error with the corresponding {@code Property} that causes the error. Does not provide a {@code Path} or {@code ThreadList}, and
+   * can therefore be used by {@code SearchListeners} to create path-less errors to ensure liveness. 
+   * 
+   * @param property the property that caused the error
+   * @see #error(Property, Path, ThreadList)
+   */
   public void error (Property property) {
     error(property, null, null);
   }
 
+  /**
+   * Creates an error with the corresponding {@code Property} that causes the error, alongside the {@code Path}, and {@code ThreadList}.
+   * 
+   * <p>Will set {@code done} to true and halt the search loop  if {@code getAllErrors} is false. If {@code getAllErrors} is true, it will 
+   * clone the {@code Property}, {@code Path}, and {@code ThreadList} objects that were passed in (as not cloning them may cause subsequent
+   * operations to overwrite information still in use) and add them to the {@code errors} list
+   * and continue verification.
+   * 
+   * <p>The property that caused the error is not reset here as the listeners attached to the search should be notified of the error first.
+   * This becomes especially problematic if one of the listeners caused the property violation, as which point it would get  confused
+   * if the {@code propertyViolated()} notification happens after the property is reset.
+   * 
+   * @param property The property that causes the error
+   * @param path The path corresponding to the error
+   * @param threadList The list of thread information corresponding to the error
+   */
   public void error (Property property, Path path, ThreadList threadList) {
 
     if (getAllErrors) {
@@ -411,17 +718,20 @@ public abstract class Search {
 
     errors.add(currentError);
 
-    // we should not reset the property until listeners have been notified
-    // (the listener might be the property itself, in which case it could get
-    // confused if propertyViolated() notifications happen after a reset)
   }
 
+  /**
+   * Resets all properties, returning violated properties to their default states.
+   */
   public void resetProperties(){
     for (Property p : properties) {
       p.reset();
     }
   }
 
+  /**
+   * Notifies the {@code SearchListener} objects in the {@code listeners} list that the search loop has advanced states.
+   */
   protected void notifyStateAdvanced () {
     try {
       for (int i = 0; i < listeners.length; i++) {
@@ -436,6 +746,10 @@ public abstract class Search {
     }
   }
 
+  /**
+   * Notifies the {@code SearchListener} objects in the {@code listeners} list that the search loop has finished processing
+   * the current state.
+   */
   protected void notifyStateProcessed() {
     try {
       for (int i = 0; i < listeners.length; i++) {
@@ -449,6 +763,9 @@ public abstract class Search {
     }
   }
 
+  /**
+   * Notifies the {@code SearchListener} objects in the {@code listeners} list that the search loop has stored the current state.
+   */
   protected void notifyStateStored() {
     try {
       for (int i = 0; i < listeners.length; i++) {
@@ -462,6 +779,10 @@ public abstract class Search {
     }
   }
 
+  /**
+   * Notifies the {@code SearchListener} objects in the {@code listeners} list that the search loop has restored a currently 
+   * stored state.
+   */
   protected void notifyStateRestored() {
     try {
       for (int i = 0; i < listeners.length; i++) {
@@ -475,6 +796,10 @@ public abstract class Search {
     }
   }
 
+  /**
+   * Notifies the {@code SearchListener} objects in the {@code listeners} list that the search loop has backtracked to a 
+   * previous state.
+   */
   protected void notifyStateBacktracked() {
     try {
       for (int i = 0; i < listeners.length; i++) {
@@ -488,6 +813,9 @@ public abstract class Search {
     }
   }
 
+  /**
+   * Notifies the {@code SearchListener} objects in the {@code listeners} list that the search loop has purged the current state.
+   */
   protected void notifyStatePurged() {
     try {
       for (int i = 0; i < listeners.length; i++) {
@@ -501,6 +829,10 @@ public abstract class Search {
     }
   }
 
+  /**
+   * Notifies the {@code SearchListener} objects in the {@code listeners} list that a probe request has been triggered during 
+   * verification.
+   */
   public void notifySearchProbed() {
     try {
       for (int i = 0; i < listeners.length; i++) {
@@ -515,6 +847,10 @@ public abstract class Search {
   }
 
   
+  /**
+   * Notifies the {@code SearchListener} objects in the {@code listeners} list that the search loop has encountered a property 
+   * violation
+   */
   protected void notifyPropertyViolated() {
     try {
       for (int i = 0; i < listeners.length; i++) {
@@ -533,6 +869,9 @@ public abstract class Search {
     }
   }
 
+  /**
+   * Notifies the {@code SearchListener} objects in the {@code listeners} list that the search loop has begun verification.
+   */
   protected void notifySearchStarted() {
     try {
       for (int i = 0; i < listeners.length; i++) {
@@ -546,6 +885,13 @@ public abstract class Search {
     }
   }
 
+  /**
+   * Notifies the {@code SearchListener} objects in the {@code listeners} list that the search loop has encountered a
+   * search constraint. The {@code details} String outlines the search constraint that was hit as well as any other
+   * relevant information.
+   * 
+   * @param details Information regarding the recent search constraint that was encountered.
+   */
   public void notifySearchConstraintHit(String details) {
     try {
       lastSearchConstraint = details;
@@ -560,6 +906,9 @@ public abstract class Search {
     }
   }
 
+  /**
+   * Notifies the {@code SearchListener} objects in the {@code listeners} list that the search loop has finished verification.
+   */
   protected void notifySearchFinished() {
     try {
       for (int i = 0; i < listeners.length; i++) {
@@ -573,6 +922,15 @@ public abstract class Search {
     }
   }
 
+  /**
+   * Requests that the virtual machine move to the next unvisited state below the current one in the search tree.
+   * {@code forward} along with {@code backtrack} constitute the two methods that are generally used to advance
+   * the search algorithm during verification.
+   * 
+   * @return true if a state exists and the virtual machine can move to it, false if the state does not exist
+   * or if it was previously explored.
+   * @see #backtrack()
+   */
   protected boolean forward () {
     currentError = null;
 
@@ -581,28 +939,76 @@ public abstract class Search {
     checkPropertyViolation();
     return ret;
   }
-
+  
+  /**
+   * Requests that the virtual machine move to the previous state in the search tree. {@code backtrack} along
+   * with {@code forward} constitute the two methods that are generally used to advance the search algorithm 
+   * during verification.
+   * 
+   * @return true if the backtrack to the previous state was successful, false otherwise
+   */
   protected boolean backtrack () {
     return vm.backtrack();
   }
 
+  /**
+   * Requests that the virtual machine sets whether the current state should be ignored in all future iterations
+   * of the search loop. This should not be used without cause as it causes the search tree to be pruned whenever
+   * it is called, which is expensive, especially in larger trees.
+   * 
+   * @param cond Whether or not the current state should be ignored
+   */
   public void setIgnoredState (boolean cond) {
     vm.ignoreState(cond);
   }
 
+  /**
+   * Restores a previously stored virtual machine state.
+   * 
+   * <p>By default this method is not supported, and therefore requires implementation logic in child classes.
+   *
+   * @param state The stored state to be restored
+   */
   protected void restoreState (State state) {
     // not supported by default
   }
 
-  /** this can be used by listeners to terminate the search */
+  /** 
+   * Sets {@code done} to true in order to terminate the search loop.
+   * 
+   * <p>Can be used by listeners to terminate the search.
+   * 
+   */
   public void terminate () {
     done = true;
   }
 
+  /**
+   * Sets the depth of the specified state given its state id.
+   * 
+   * <p>When the depth of the state is set, it is set as depth + 1. This is to differentiate between
+   * states that have had their depths set, and states that have not (in which case their default depth
+   * will be 0).
+   * 
+   * @param stateId The state in question
+   * @param depth The new depth to set for the state
+   */
   protected void setStateDepth (int stateId, int depth) {
     stateDepth.set(stateId, depth + 1);
   }
 
+  
+  /**
+   * Returns the saved depth of the specified state given its state id.
+   * 
+   * <p>If the state in question has not had its state depth set previously, then it will by default have
+   * a depth that is less than or equal to 0. Otherwise if the state has been visited, the depth will be 
+   * returned.
+   * 
+   * @param stateId The state to return the depth of
+   * @return The depth of the specified state
+   * @throws JPFException If the state has not been visited in the past
+   */
   public int getStateDepth (int stateId) {
     int depthPlusOne = stateDepth.get(stateId);
     if (depthPlusOne <= 0) {
@@ -613,9 +1019,15 @@ public abstract class Search {
   }
 
   /**
-   * check if we have a minimum amount of free memory left. If not, we rather want to stop in time
-   * (with a threshold amount left) so that we can report something useful, and not just die silently
-   * with a OutOfMemoryError (which isn't handled too gracefully by most VMs)
+   * Check if there is the minimum amount of free memory left or more. If not, we would rather stop in time
+   * (with a threshold amount left) in order to report something useful, and not just end verification silently
+   * with a OutOfMemoryError (which is not handled too gracefully by most VMs)
+   * 
+   * <p>If the minimum amount of memory has been reached, the method will first try to activate garbage collection
+   * and then check again if that made a difference. If the amount of memory available is still less than the 
+   * minimum amount of memory, then we return false.
+   * 
+   * @return true if we have more memory than the minimum free memory, false otherwise.
    */
   public boolean checkStateSpaceLimit () {
     Runtime rt = Runtime.getRuntime();