private bool HasInvariantField(VariableEffect p)
 {
     if (p.FieldChain.Count > 0)
     {
         Field f = p.FieldChain[p.FieldChain.Count - 1];
         if (f.IsRep || (!(f is PTExtraField) && f.Type.IsValueType))
             return true;
     }
     return false;
 }
    public void CheckReadEffectAdmissibility(Set<VariableEffect> readEffects) {
      foreach (VariableEffect readEffect in readEffects) {
        currentEffect = readEffect;
        List<Field> chain = readEffect.FieldChain;
        Variable v = readEffect.Variable;

        if (chain == null) return;
        if (v.Name.ToString().Equals("Global")) {  // Global read is not admitted
          if (chain.Count != 1 || !GlobalFieldIsPrivateOrImmutable(chain[0]))
            this.IssueWarning();
        }
        ResetState();
        if (v is Parameter && !(v is This)) {  // chain accesses parameter
          firstBoundMember = false;
          outsideOwnedCone = true; // since we do not allow rep annotation on parameters
        }
        for (int i = 0; i < chain.Count; i++)
          CheckField(chain[i]);
      }
    }
        public Set<VariableEffect> ComputePathsFromVariableToHeapLocation(Set<IPTAnalysisNode> ns, Label lb)
        {
            Set<VariableEffect> variableEffects = new Set<VariableEffect>();

            //if (WriteEffects.HasWriteEffects)
            //    Console.Out.WriteLine("Modifies:");

            // Traverse every write effect
            foreach (IPTAnalysisNode n in ns)
            {
                // Get the fields that are backward reachable from the modified field
                Set<List<Edge>> paths = PointsToGraph.DFSPathFrom(n, false, true, true);
                foreach (List<Edge> currentPath in paths)
                {
                    currentPath.Reverse();

                    IPTAnalysisNode rootNode;

                    if (currentPath.Count > 0)
                        rootNode = currentPath[0].Src;
                    else
                        rootNode = n;

                    Variable v = null;
                    
                    if (rootNode.IsVariableReference)
                    {
                        IVarRefNode vrNode = rootNode as IVarRefNode;
                        v = vrNode.ReferencedVariable;
                        if (!IsLocal(v))
                            continue;
                        //if (!(v is Parameter) && !v.Equals(PTGraph.GlobalScope))
                        //    continue;
                    }

                    if (rootNode.Equals(GNode.nGBL))
                    {
                        v = PTGraph.GlobalScope;
                    }
                    
                    /*
                    if (rootNode.IsParameterNode && ((PNode)rootNode).IsByValue)
                    {
                        bool fieldUpdate = !n.Field.Equals(PTGraph.asterisk);
                        foreach (Edge e in currentPath)
                            fieldUpdate = fieldUpdate || !e.Field.Equals(PTGraph.asterisk);
                        if (!fieldUpdate)
                            continue;
                    }
                    */
                    string nodeName = rootNode.Name;

                    if (v != null)
                    {
                        VariableEffect vEffect = new VariableEffect(v, lb);
                        foreach (Edge e in currentPath)
                        {
                            if (!e.Field.Equals(PTGraph.asterisk))
                            {
                                vEffect.AddField(e.Field);
                                // lastField = e.Field;
                            }
                        }
                        variableEffects.Add(vEffect);
                    }

                }
            }
            return variableEffects;
            
        }