gt: 		LE result = derivedCache.get(objects);
context: /**
   * Copyright (C) 2007, 2008 Carnegie Mellon University and others.
   *
   * This file is part of Plural.
   *
   * Plural is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
   *
   * Plural is distributed in the hope that it will be useful, but
   * WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   * General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with Plural; if not, see <http://www.gnu.org/licenses>.
   *
   * Linking Plural statically or dynamically with other modules is
   * making a combined work based on Plural. Thus, the terms and
   * conditions of the GNU General Public License cover the whole
   * combination.
   *
   * In addition, as a special exception, the copyright holders of Plural
   * give you permission to combine Plural with free software programs or
   * libraries that are released under the GNU LGPL and with code
   * included in the standard release of Eclipse under the Eclipse Public
   * License (or modified versions of such code, with unchanged license).
   * You may copy and distribute such a system following the terms of the
   * GNU GPL for Plural and the licenses of the other code concerned.
   *
   * Note that people who make modified versions of Plural are not
   * obligated to grant this special exception for their modified
   * versions; it is their choice whether to do so. The GNU General
   * Public License gives permission to release a modified version
   * without this exception; this exception also makes it possible to
   * release a modified version which carries forward this exception.
   */
  package edu.cmu.cs.plural.alias;
  
  import java.util.Collections;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.LinkedHashSet;
  import java.util.Map;
  import java.util.Set;
  
  import org.eclipse.jdt.core.dom.ASTNode;
  import org.eclipse.jdt.core.dom.IVariableBinding;
  import org.eclipse.jdt.core.dom.MethodDeclaration;
  
  import edu.cmu.cs.crystal.IAnalysisInput;
  import edu.cmu.cs.crystal.analysis.alias.Aliasing;
  import edu.cmu.cs.crystal.analysis.alias.ObjectLabel;
  import edu.cmu.cs.crystal.bridge.LatticeElement;
  import edu.cmu.cs.crystal.tac.ITACFlowAnalysis;
  import edu.cmu.cs.crystal.tac.TACFlowAnalysis;
  import edu.cmu.cs.crystal.tac.model.TACInstruction;
  import edu.cmu.cs.crystal.tac.model.Variable;
  import edu.cmu.cs.crystal.util.CollectionMethods;
  import edu.cmu.cs.crystal.util.ExtendedIterator;
  import edu.cmu.cs.crystal.util.Freezable;
  import edu.cmu.cs.crystal.util.Lambda;
  import edu.cmu.cs.plural.util.ReplacementGenerator;
  
  /**
   * This is an alias-aware tuple lattice implementation. It automatically
   * translates AST nodes and variables into sets of locations they may point to
   * and keeps aliasing information for overlapping sets consistent. Analysis
   * information can be retrieved with <code>get()</code> methods and updated
   * with <code>put()</code> methods. In case you need the aliasing information
   * yourself, the methods <code>getLocationsXxx()</code> let you find out what
   * locations a variable might point to before/after a given instruction.
   * 
   * This class implements a protocol to reduce copying overhead. When you call
   * {@link #freeze()}, or when it's copied or joined, the object freezes itself,
   * not allowing future changes. In order to change something, you have to call
   * {@link #mutableCopy()} and make the change on the copy. As a general rule, if
   * a transfer method wants to change the tuple it needs to call mutableCopy()
   * once, in the beginning, and make sure that that new object is used in the
   * result it returns. 
   * 
   * AliasAwareTupleLE is unfortunately not quite interface-compatible with
   * TupleLatticeElement: <code>get()</code> and <code>put()</code> take not
   * only the variable you're interested in, but also the TACInstruction for which
   * you're updating. This is so the thing can internally look up what the
   * aliasing analysis has to say about that instruction. It's a little
   * unpleasant, but that's the best way I could figure out so far how to do this.
   * Anyway, you're going to have to add the instruction to all these calls.
   * 
   * @author Kevin Bierhoff
   * @since Crystal 3.3.0
   * @see edu.cmu.cs.crystal.simple.TupleLatticeElement
   */
  public class AliasAwareTupleLE<LE extends LatticeElement<LE>> implements
  	Freezable<AliasAwareTupleLE<LE>>,	
  	MutableAliasAwareTuple<LE>, Iterable<LE> {
  
  	/**
  	 * Creates an initial lattice element that will throw an exception if
  	 * information about unknown variables is requested.
  	 * @param b 
  	 * @param adb 
  	 * 
  	 * @param <LE>
  	 * @return
  	 */
  	public static <LE extends LatticeElement<LE>> AliasAwareTupleLE<LE> create(final IAnalysisInput input) {
  		return new AliasAwareTupleLE<LE>(input, new TupleCallback<LE>() {
  			public LE defaultResult(Aliasing a) {
  				throw new IllegalStateException(
  						"Information for unknown alias set requested.");
  			}
  		});
  	}
  
  	/**
  	 * Creates an initial lattice element that will return the given bottom
  	 * value if information about unknown variables is requested.
  	 * 
  	 * @param <LE>
  	 * @return
  	 */
  	public static <LE extends LatticeElement<LE>> AliasAwareTupleLE<LE> create(
  			final IAnalysisInput input,
  			final LE bottom) {
  		return new AliasAwareTupleLE<LE>(input, new TupleCallback<LE>() {
  			public LE defaultResult(Aliasing a) {
  				return bottom;
  			}
  		});
  	}
  
  	/**
  	 * Callback interface to customize AliasAwareTupleLE's behavior in case of
  	 * missing values. This method will be called for aliasing sets for which no
  	 * analysis information is available or derivable.
  	 * 
  	 * @author Kevin Bierhoff
  	 * 
  	 * @param <LE>
  	 */
  	public interface TupleCallback<LE extends LatticeElement<LE>> {
  
  		/**
  		 * This method should return a valid analysis information object about
  		 * the given aliasing set.
  		 * 
  		 * @param a
  		 * @return A valid non-<code>null</code> analysis information object
  		 *         about the given aliasing set.
  		 */
  		LE defaultResult(Aliasing a);
  
  	}
  	
  	/**
  	 * Filter callback interface for locations.
  	 * @author Kevin Bierhoff
  	 * @since 8/15/2008
  	 * @see AliasAwareTupleLE#removeLocations(edu.cmu.cs.plural.alias.AliasAwareTupleLE.LabelFilter)
  	 */
  	public interface LabelFilter {
  
  		/**
  		 * Indicate whether the given label should be considered, in the context
  		 * this filter is used.
  		 * @param l
  		 * @return <code>true</code> if the given label should be considered,
  		 * <code>false</code> otherwise.
  		 */
  		boolean isConsidered(ObjectLabel l);
  		
  	}
  
  	/** Local aliasing analysis information. */
  	private final ITACFlowAnalysis<AliasingLE> aliasing;
  
  	/** The actual analysis information this tuple keeps track of. */
  	private final Map<ObjectLabel, LE> info;
  
  	/** Callback interface to customize the tuple's behavior. */
  	private final TupleCallback<LE> callback;
  
  	/**
  	 * Aliasing sets that have been checked to be at least as precise as their
  	 * subsets. This set helps making the tuple implementation more efficient
  	 * and, when in doubt, should be cleared whenever aliasing information is
  	 * modified.
  	 */
  	private final Map<Aliasing, LE> derivedCache;
  
  	/**
  	 * Flag indicating whether the tuple was frozen. Once frozen, a tuple must
  	 * not be modified ever again.
  	 */
  	private boolean frozen;
  
  	/**
  	 * This map contains fields of 'this' and the labels they are associated with.
  	 * This map is actually built up by the this.aliasing flow analysis, and we
  	 * just hold reference to it so that we will have the mappings at a later point.
  	 */
  	private final Map<IVariableBinding, Variable> receiverFields;
  	
  	/**
  	 * Creates an initial lattice element that will invoke the given callback
  	 * interface where needed.
  	 * @param adb 
  	 * 
  	 * @param callback
  	 */
  	public AliasAwareTupleLE(IAnalysisInput input, TupleCallback<LE> callback) {
  		Map<IVariableBinding, Variable> receiverFields = new HashMap<IVariableBinding, Variable>();
  		this.aliasing = new TACFlowAnalysis<AliasingLE>(
  				// pass modifiable map into LocalAliasTransfer
  				new LocalAliasTransfer(input.getAnnoDB(), receiverFields),
  				input.getComUnitTACs().unwrap());
  		this.info = new HashMap<ObjectLabel, LE>();
  		this.derivedCache = new HashMap<Aliasing, LE>();
  		this.callback = callback;
  		// make this's field a unmodifiable view
  		this.receiverFields = Collections.unmodifiableMap(receiverFields);
  	}
  
  	/**
  	 * Internal constructor to create lattice elements based on an existing one.
  	 * 
  	 * @param aliasing
  	 * @param info
  	 * @param callback
  	 * @param receiverFields 
  	 */
  	private AliasAwareTupleLE(
  			ITACFlowAnalysis<AliasingLE> aliasing,
  			Map<ObjectLabel, LE> info, TupleCallback<LE> callback,
  			Map<IVariableBinding, Variable> receiverFields) {
  		this.aliasing = aliasing;
  		this.info = info;
  		this.derivedCache = new HashMap<Aliasing, LE>();
  		this.callback = callback;
  		this.receiverFields = receiverFields; 
  	}
  
  	/**
  	 * Returns analysis information for the given variable using aliasing
  	 * information after the given node was evaluated.
  	 * 
  	 * @param n
  	 * @param x
  	 * @return Analysis information for the given node after the node was
  	 *         evaluated.
  	 */
  	public LE get(ASTNode n, Variable x) {
  		return get(getLocations(n, x));
  	}
  
  	/**
  	 * Returns analysis information for the given variable using
  	 * aliasing information after the given instruction was evaluated.
  	 * 
  	 * @param instr
  	 * @param x
  	 * @return Analysis information for the given variable before the given
  	 *         instruction was evaluated.
  	 */
  	public LE get(TACInstruction instr, Variable x) {
  		return get(getLocations(instr, x));
  	}
  	
  	/**
  	 * Returns analysis information for the given aliasing set.
  	 * 
  	 * @param objects
  	 * @return Analysis information for the given aliasing set.
  	 */
  	public LE get(Aliasing objects) {
  		if( this.isBottom() )
  			return defaultResult(objects);
  		
  