text:
using namespace llvm;
using namespace llvm::cflaa;

#define DEBUG_TYPE "cfl-anders-aa"

CFLAndersAAResult::CFLAndersAAResult(const TargetLibraryInfo &TLI) : TLI(TLI) {}
CFLAndersAAResult::CFLAndersAAResult(CFLAndersAAResult &&RHS)
    : AAResultBase(std::move(RHS)), TLI(RHS.TLI) {}
CFLAndersAAResult::~CFLAndersAAResult() {}

static const Function *parentFunctionOfValue(const Value *Val) {
  if (auto *Inst = dyn_cast<Instruction>(Val)) {
    auto *Bb = Inst->getParent();
    return Bb->getParent();
  }

  if (auto *Arg = dyn_cast<Argument>(Val))
    return Arg->getParent();
  return nullptr;
}

namespace {

enum class MatchState : uint8_t {
  // The following state represents S1 in the paper.
  FlowFromReadOnly = 0,
  // The following two states together represent S2 in the paper.
  // The 'NoReadWrite' suffix indicates that there exists an alias path that
  // does not contain assignment and reverse assignment edges.
  // The 'ReadOnly' suffix indicates that there exists an alias path that
  // contains reverse assignment edges only.
  FlowFromMemAliasNoReadWrite,
  FlowFromMemAliasReadOnly,
  // The following two states together represent S3 in the paper.
  // The 'WriteOnly' suffix indicates that there exists an alias path that
  // contains assignment edges only.
  // The 'ReadWrite' suffix indicates that there exists an alias path that
  // contains both assignment and reverse assignment edges. Note that if X and Y
  // are reachable at 'ReadWrite' state, it does NOT mean X is both read from
  // and written to Y. Instead, it means that a third value Z is written to both
  // X and Y.
  FlowToWriteOnly,
  FlowToReadWrite,
  // The following two states together represent S4 in the paper.
  FlowToMemAliasWriteOnly,
  FlowToMemAliasReadWrite,
};

typedef std::bitset<7> StateSet;
const unsigned ReadOnlyStateMask =
    (1U << static_cast<uint8_t>(MatchState::FlowFromReadOnly)) |
    (1U << static_cast<uint8_t>(MatchState::FlowFromMemAliasReadOnly));
const unsigned WriteOnlyStateMask =
    (1U << static_cast<uint8_t>(MatchState::FlowToWriteOnly)) |
    (1U << static_cast<uint8_t>(MatchState::FlowToMemAliasWriteOnly));

// A pair that consists of a value and an offset
struct OffsetValue {
  const Value *Val;
  int64_t Offset;
};

bool operator==(OffsetValue LHS, OffsetValue RHS) {
  return LHS.Val == RHS.Val && LHS.Offset == RHS.Offset;
}
bool operator<(OffsetValue LHS, OffsetValue RHS) {
  return std::less<const Value *>()(LHS.Val, RHS.Val) ||
         (LHS.Val == RHS.Val && LHS.Offset < RHS.Offset);
}

// A pair that consists of an InstantiatedValue and an offset
struct OffsetInstantiatedValue {
  InstantiatedValue IVal;
  int64_t Offset;
};

bool operator==(OffsetInstantiatedValue LHS, OffsetInstantiatedValue RHS) {
  return LHS.IVal == RHS.IVal && LHS.Offset == RHS.Offset;
}

// We use ReachabilitySet to keep track of value aliases (The nonterminal "V" in
// the paper) during the analysis.
class ReachabilitySet {
  typedef DenseMap<InstantiatedValue, StateSet> ValueStateMap;
  typedef DenseMap<InstantiatedValue, ValueStateMap> ValueReachMap;
  ValueReachMap ReachMap;

public:
  typedef ValueStateMap::const_iterator const_valuestate_iterator;
  typedef ValueReachMap::const_iterator const_value_iterator;

  // Insert edge 'From->To' at state 'State'
  bool insert(InstantiatedValue From, InstantiatedValue To, MatchState State) {
    assert(From != To);
    auto &States = ReachMap[To][From];
    auto Idx = static_cast<size_t>(State);
    if (!States.test(Idx)) {
      States.set(Idx);
      return true;
    }
    return false;
  }

  // Return the set of all ('From', 'State') pair for a given node 'To'
  iterator_range<const_valuestate_iterator>
  reachableValueAliases(InstantiatedValue V) const {
    auto Itr = ReachMap.find(V);
    if (Itr == ReachMap.end())
      return make_range<const_valuestate_iterator>(const_valuestate_iterator(),
                                                   const_valuestate_iterator());
    return make_range<const_valuestate_iterator>(Itr->second.begin(),
                                                 Itr->second.end());
  }

  iterator_range<const_value_iterator> value_mappings() const {
    return make_range<const_value_iterator>(ReachMap.begin(), ReachMap.end());
  }
};

// We use AliasMemSet to keep track of all memory aliases (the nonterminal "M"
// in the paper) during the analysis.
class AliasMemSet {
  typedef DenseSet<InstantiatedValue> MemSet;
  typedef DenseMap<InstantiatedValue, MemSet> MemMapType;
  MemMapType MemMap;

public:
  typedef MemSet::const_iterator const_mem_iterator;

  bool insert(InstantiatedValue LHS, InstantiatedValue RHS) {
    // Top-level values can never be memory aliases because one cannot take the
    // addresses of them
    assert(LHS.DerefLevel > 0 && RHS.DerefLevel > 0);
    return MemMap[LHS].insert(RHS).second;
  }

  const MemSet *getMemoryAliases(InstantiatedValue V) const {
    auto Itr = MemMap.find(V);
    if (Itr == MemMap.end())
      return nullptr;
    return &Itr->second;
  }
};

// We use AliasAttrMap to keep track of the AliasAttr of each node.
class AliasAttrMap {
  typedef DenseMap<InstantiatedValue, AliasAttrs> MapType;
  MapType AttrMap;

public:
  typedef MapType::const_iterator const_iterator;

  bool add(InstantiatedValue V, AliasAttrs Attr) {
    auto &OldAttr = AttrMap[V];
    auto NewAttr = OldAttr | Attr;
    if (OldAttr == NewAttr)
      return false;
    OldAttr = NewAttr;
    return true;
  }

  AliasAttrs getAttrs(InstantiatedValue V) const {
    AliasAttrs Attr;
    auto Itr = AttrMap.find(V);
    if (Itr != AttrMap.end())
      Attr = Itr->second;
    return Attr;
  }

  iterator_range<const_iterator> mappings() const {
    return make_range<const_iterator>(AttrMap.begin(), AttrMap.end());
  }
};

struct WorkListItem {
  InstantiatedValue From;
  InstantiatedValue To;
  MatchState State;
};

struct ValueSummary {
  struct Record {
    InterfaceValue IValue;
    unsigned DerefLevel;
  };
  SmallVector<Record, 4> FromRecords, ToRecords;
};
}

namespace llvm {
// Specialize DenseMapInfo for OffsetValue.
template <> struct DenseMapInfo<OffsetValue> {
  static OffsetValue getEmptyKey() {
    return OffsetValue{DenseMapInfo<const Value *>::getEmptyKey(),
                       DenseMapInfo<int64_t>::getEmptyKey()};
  }
  static OffsetValue getTombstoneKey() {
    return OffsetValue{DenseMapInfo<const Value *>::getTombstoneKey(),
                       DenseMapInfo<int64_t>::getEmptyKey()};
  }
  static unsigned getHashValue(const OffsetValue &OVal) {
    return DenseMapInfo<std::pair<const Value *, int64_t>>::getHashValue(
        std::make_pair(OVal.Val, OVal.Offset));
  }
  static bool isEqual(const OffsetValue &LHS, const OffsetValue &RHS) {
    return LHS == RHS;
  }
};

// Specialize DenseMapInfo for OffsetInstantiatedValue.
template <> struct DenseMapInfo<OffsetInstantiatedValue> {
  static OffsetInstantiatedValue getEmptyKey() {
    return OffsetInstantiatedValue{
        DenseMapInfo<InstantiatedValue>::getEmptyKey(),
        DenseMapInfo<int64_t>::getEmptyKey()};
  }
  static OffsetInstantiatedValue getTombstoneKey() {
    return OffsetInstantiatedValue{
        DenseMapInfo<InstantiatedValue>::getTombstoneKey(),
        DenseMapInfo<int64_t>::getEmptyKey()};
  }
  static unsigned getHashValue(const OffsetInstantiatedValue &OVal) {
    return DenseMapInfo<std::pair<InstantiatedValue, int64_t>>::getHashValue(
        std::make_pair(OVal.IVal, OVal.Offset));
  }
  static bool isEqual(const OffsetInstantiatedValue &LHS,
                      const OffsetInstantiatedValue &RHS) {
    return LHS == RHS;
  }
};
}

class CFLAndersAAResult::FunctionInfo {
  /// Map a value to other values that may alias it
  /// Since the alias relation is symmetric, to save some space we assume values
  /// are properly ordered: if a and b alias each other, and a < b, then b is in
  /// AliasMap[a] but not vice versa.
  DenseMap<const Value *, std::vector<OffsetValue>> AliasMap;

  /// Map a value to its corresponding AliasAttrs
  DenseMap<const Value *, AliasAttrs> AttrMap;

  /// Summary of externally visible effects.
  AliasSummary Summary;

  Optional<AliasAttrs> getAttrs(const Value *) const;

public:
  FunctionInfo(const Function &, const SmallVectorImpl<Value *> &,
               const ReachabilitySet &, AliasAttrMap);

  bool mayAlias(const Value *, uint64_t, const Value *, uint64_t) const;
  const AliasSummary &getAliasSummary() const { return Summary; }
};

static bool hasReadOnlyState(StateSet Set) {
  return (Set & StateSet(ReadOnlyStateMask)).any();
}

static bool hasWriteOnlyState(StateSet Set) {
  return (Set & StateSet(WriteOnlyStateMask)).any();
}

static Optional<InterfaceValue>
getInterfaceValue(InstantiatedValue IValue,
                  const SmallVectorImpl<Value *> &RetVals) {
  auto Val = IValue.Val;

  Optional<unsigned> Index;
  if (auto Arg = dyn_cast<Argument>(Val))
    Index = Arg->getArgNo() + 1;
  else if (is_contained(RetVals, Val))
    Index = 0;

  if (Index)
    return InterfaceValue{*Index, IValue.DerefLevel};
  return None;
}

static void populateAttrMap(DenseMap<const Value *, AliasAttrs> &AttrMap,
                            const AliasAttrMap &AMap) {
  for (const auto &Mapping : AMap.mappings()) {
    auto IVal = Mapping.first;

    // Insert IVal into the map
    auto &Attr = AttrMap[IVal.Val];
    // AttrMap only cares about top-level values
    if (IVal.DerefLevel == 0)
      Attr |= Mapping.second;
  }
}

static void
populateAliasMap(DenseMap<const Value *, std::vector<OffsetValue>> &AliasMap,
                 const ReachabilitySet &ReachSet) {
  for (const auto &OuterMapping : ReachSet.value_mappings()) {
    // AliasMap only cares about top-level values
    if (OuterMapping.first.DerefLevel > 0)
      continue;

    auto Val = OuterMapping.first.Val;
    auto &AliasList = AliasMap[Val];
    for (const auto &InnerMapping : OuterMapping.second) {
      // Again, AliasMap only cares about top-level values
      if (InnerMapping.first.DerefLevel == 0)
        AliasList.push_back(OffsetValue{InnerMapping.first.Val, UnknownOffset});
    }

    // Sort AliasList for faster lookup
    std::sort(AliasList.begin(), AliasList.end());
  }
}

static void populateExternalRelations(
    SmallVectorImpl<ExternalRelation> &ExtRelations, const Function &Fn,
    const SmallVectorImpl<Value *> &RetVals, const ReachabilitySet &ReachSet) {
  // If a function only returns one of its argument X, then X will be both an
  // argument and a return value at the same time. This is an edge case that
  // needs special handling here.
  for (const auto &Arg : Fn.args()) {
    if (is_contained(RetVals, &Arg)) {
      auto ArgVal = InterfaceValue{Arg.getArgNo() + 1, 0};
      auto RetVal = InterfaceValue{0, 0};
      ExtRelations.push_back(ExternalRelation{ArgVal, RetVal, 0});
    }
  }

  // Below is the core summary construction logic.
  // A naive solution of adding only the value aliases that are parameters or
  // return values in ReachSet to the summary won't work: It is possible that a
  // parameter P is written into an intermediate value I, and the function
  // subsequently returns *I. In that case, *I is does not value alias anything
  // in ReachSet, and the naive solution will miss a summary edge from (P, 1) to
  // (I, 1).
  // To account for the aforementioned case, we need to check each non-parameter
  // and non-return value for the possibility of acting as an intermediate.
  // 'ValueMap' here records, for each value, which InterfaceValues read from or
  // write into it. If both the read list and the write list of a given value
  // are non-empty, we know that a particular value is an intermidate and we
  // need to add summary edges from the writes to the reads.
  DenseMap<Value *, ValueSummary> ValueMap;
  for (const auto &OuterMapping : ReachSet.value_mappings()) {
    if (auto Dst = getInterfaceValue(OuterMapping.first, RetVals)) {
      for (const auto &InnerMapping : OuterMapping.second) {
        // If Src is a param/return value, we get a same-level assignment.
        if (auto Src = getInterfaceValue(InnerMapping.first, RetVals)) {
          // This may happen if both Dst and Src are return values
          if (*Dst == *Src)
            continue;

          if (hasReadOnlyState(InnerMapping.second))
            ExtRelations.push_back(ExternalRelation{*Dst, *Src, UnknownOffset});
          // No need to check for WriteOnly state, since ReachSet is symmetric
        } else {
          // If Src is not a param/return, add it to ValueMap
          auto SrcIVal = InnerMapping.first;
          if (hasReadOnlyState(InnerMapping.second))
            ValueMap[SrcIVal.Val].FromRecords.push_back(
                ValueSummary::Record{*Dst, SrcIVal.DerefLevel});
          if (hasWriteOnlyState(InnerMapping.second))
            ValueMap[SrcIVal.Val].ToRecords.push_back(
                ValueSummary::Record{*Dst, SrcIVal.DerefLevel});
        }
      }
    }
  }

  for (const auto &Mapping : ValueMap) {
    for (const auto &FromRecord : Mapping.second.FromRecords) {
      for (const auto &ToRecord : Mapping.second.ToRecords) {
        auto ToLevel = ToRecord.DerefLevel;
        auto FromLevel = FromRecord.DerefLevel;
        // Same-level assignments should have already been processed by now
        if (ToLevel == FromLevel)
          continue;

        auto SrcIndex = FromRecord.IValue.Index;
        auto SrcLevel = FromRecord.IValue.DerefLevel;
        auto DstIndex = ToRecord.IValue.Index;
        auto DstLevel = ToRecord.IValue.DerefLevel;
        if (ToLevel > FromLevel)
          SrcLevel += ToLevel - FromLevel;
        else
          DstLevel += FromLevel - ToLevel;

        ExtRelations.push_back(ExternalRelation{
            InterfaceValue{SrcIndex, SrcLevel},
            InterfaceValue{DstIndex, DstLevel}, UnknownOffset});
      }
    }
  }

  // Remove duplicates in ExtRelations
  std::sort(ExtRelations.begin(), ExtRelations.end());
  ExtRelations.erase(std::unique(ExtRelations.begin(), ExtRelations.end()),
                     ExtRelations.end());
}

static void populateExternalAttributes(
    SmallVectorImpl<ExternalAttribute> &ExtAttributes, const Function &Fn,
    const SmallVectorImpl<Value *> &RetVals, const AliasAttrMap &AMap) {
  for (const auto &Mapping : AMap.mappings()) {
    if (auto IVal = getInterfaceValue(Mapping.first, RetVals)) {
      auto Attr = getExternallyVisibleAttrs(Mapping.second);
      if (Attr.any())
        ExtAttributes.push_back(ExternalAttribute{*IVal, Attr});
    }
  }
}

CFLAndersAAResult::FunctionInfo::FunctionInfo(
    const Function &Fn, const SmallVectorImpl<Value *> &RetVals,
    const ReachabilitySet &ReachSet, AliasAttrMap AMap) {
  populateAttrMap(AttrMap, AMap);
  populateExternalAttributes(Summary.RetParamAttributes, Fn, RetVals, AMap);
  populateAliasMap(AliasMap, ReachSet);
  populateExternalRelations(Summary.RetParamRelations, Fn, RetVals, ReachSet);
}

Optional<AliasAttrs>
CFLAndersAAResult::FunctionInfo::getAttrs(const Value *V) const {
  assert(V != nullptr);

  auto Itr = AttrMap.find(V);
  if (Itr != AttrMap.end())
    return Itr->second;
  return None;
}

bool CFLAndersAAResult::FunctionInfo::mayAlias(const Value *LHS,
                                               uint64_t LHSSize,
                                               const Value *RHS,
                                               uint64_t RHSSize) const {
  assert(LHS && RHS);

  // Check if we've seen LHS and RHS before. Sometimes LHS or RHS can be created
  // after the analysis gets executed, and we want to be conservative in those
  // cases.
  auto MaybeAttrsA = getAttrs(LHS);
  auto MaybeAttrsB = getAttrs(RHS);
  if (!MaybeAttrsA || !MaybeAttrsB)
    return true;

  // Check AliasAttrs before AliasMap lookup since it's cheaper
  auto AttrsA = *MaybeAttrsA;
  auto AttrsB = *MaybeAttrsB;
  if (hasUnknownOrCallerAttr(AttrsA))
    return AttrsB.any();
  if (hasUnknownOrCallerAttr(AttrsB))
    return AttrsA.any();
  if (isGlobalOrArgAttr(AttrsA))
    return isGlobalOrArgAttr(AttrsB);
  if (isGlobalOrArgAttr(AttrsB))
    return isGlobalOrArgAttr(AttrsA);

  // At this point both LHS and RHS should point to locally allocated objects

  auto Itr = AliasMap.find(LHS);
  if (Itr != AliasMap.end()) {

    // Find out all (X, Offset) where X == RHS
    auto Comparator = [](OffsetValue LHS, OffsetValue RHS) {
      return std::less<const Value *>()(LHS.Val, RHS.Val);
    };
#ifdef EXPENSIVE_CHECKS
    assert(std::is_sorted(Itr->second.begin(), Itr->second.end(), Comparator));
#endif
    auto RangePair = std::equal_range(Itr->second.begin(), Itr->second.end(),
                                      OffsetValue{RHS, 0}, Comparator);

    if (RangePair.first != RangePair.second) {
      // Be conservative about UnknownSize
      if (LHSSize == MemoryLocation::UnknownSize ||
          RHSSize == MemoryLocation::UnknownSize)
        return true;

      for (const auto &OVal : make_range(RangePair)) {
        // Be conservative about UnknownOffset
        if (OVal.Offset == UnknownOffset)
          return true;

        // We know that LHS aliases (RHS + OVal.Offset) if the control flow
        // reaches here. The may-alias query essentially becomes integer
        // range-overlap queries over two ranges [OVal.Offset, OVal.Offset +
        // LHSSize) and [0, RHSSize).

        // Try to be conservative on super large offsets
        if (LLVM_UNLIKELY(LHSSize > INT64_MAX || RHSSize > INT64_MAX))
          return true;

        auto LHSStart = OVal.Offset;
        // FIXME: Do we need to guard against integer overflow?
        auto LHSEnd = OVal.Offset + static_cast<int64_t>(LHSSize);
        auto RHSStart = 0;
        auto RHSEnd = static_cast<int64_t>(RHSSize);
        if (LHSEnd > RHSStart && LHSStart < RHSEnd)
          return true;
      }
    }
  }

  return false;
}

static void propagate(InstantiatedValue From, InstantiatedValue To,
                      MatchState State, ReachabilitySet &ReachSet,
                      std::vector<WorkListItem> &WorkList) {
  if (From == To)
    return;
  if (ReachSet.insert(From, To, State))
    WorkList.push_back(WorkListItem{From, To, State});
}

static void initializeWorkList(std::vector<WorkListItem> &WorkList,
                               ReachabilitySet &ReachSet,
                               const CFLGraph &Graph) {
  for (const auto &Mapping : Graph.value_mappings()) {
    auto Val = Mapping.first;
    auto &ValueInfo = Mapping.second;
    assert(ValueInfo.getNumLevels() > 0);

    // Insert all immediate assignment neighbors to the worklist
    for (unsigned I = 0, E = ValueInfo.getNumLevels(); I < E; ++I) {
      auto Src = InstantiatedValue{Val, I};
      // If there's an assignment edge from X to Y, it means Y is reachable from
      // X at S2 and X is reachable from Y at S1
      for (auto &Edge : ValueInfo.getNodeInfoAtLevel(I).Edges) {
        propagate(Edge.Other, Src, MatchState::FlowFromReadOnly, ReachSet,
                  WorkList);
        propagate(Src, Edge.Other, MatchState::FlowToWriteOnly, ReachSet,
                  WorkList);
      }
    }
  }
}

static Optional<InstantiatedValue> getNodeBelow(const CFLGraph &Graph,
                                                InstantiatedValue V) {
  auto NodeBelow = InstantiatedValue{V.Val, V.DerefLevel + 1};
  if (Graph.getNode(NodeBelow))
    return NodeBelow;
  return None;
}

static void processWorkListItem(const WorkListItem &Item, const CFLGraph &Graph,
                                ReachabilitySet &ReachSet, AliasMemSet &MemSet,
                                std::vector<WorkListItem> &WorkList) {
  auto FromNode = Item.From;
  auto ToNode = Item.To;

  auto NodeInfo = Graph.getNode(ToNode);
  assert(NodeInfo != nullptr);

  // TODO: propagate field offsets

  // FIXME: Here is a neat trick we can do: since both ReachSet and MemSet holds
  // relations that are symmetric, we could actually cut the storage by half by
  // sorting FromNode and ToNode before insertion happens.

  // The newly added value alias pair may pontentially generate more memory
  // alias pairs. Check for them here.
  auto FromNodeBelow = getNodeBelow(Graph, FromNode);
  auto ToNodeBelow = getNodeBelow(Graph, ToNode);
  if (FromNodeBelow && ToNodeBelow &&
      MemSet.insert(*FromNodeBelow, *ToNodeBelow)) {
    propagate(*FromNodeBelow, *ToNodeBelow,
              MatchState::FlowFromMemAliasNoReadWrite, ReachSet, WorkList);
    for (const auto &Mapping : ReachSet.reachableValueAliases(*FromNodeBelow)) {
      auto Src = Mapping.first;
      auto MemAliasPropagate = [&](MatchState FromState, MatchState ToState) {
        if (Mapping.second.test(static_cast<size_t>(FromState)))
          propagate(Src, *ToNodeBelow, ToState, ReachSet, WorkList);
      };

      MemAliasPropagate(MatchState::FlowFromReadOnly,
                        MatchState::FlowFromMemAliasReadOnly);
      MemAliasPropagate(MatchState::FlowToWriteOnly,
                        MatchState::FlowToMemAliasWriteOnly);
      MemAliasPropagate(MatchState::FlowToReadWrite,
                        MatchState::FlowToMemAliasReadWrite);
    }
  }

  // This is the core of the state machine walking algorithm. We expand ReachSet
  // based on which state we are at (which in turn dictates what edges we
  // should examine)
  // From a high-level point of view, the state machine here guarantees two
  // properties:
  // - If *X and *Y are memory aliases, then X and Y are value aliases
  // - If Y is an alias of X, then reverse assignment edges (if there is any)
  // should precede any assignment edges on the path from X to Y.
  auto NextAssignState = [&](MatchState State) {
    for (const auto &AssignEdge : NodeInfo->Edges)
      propagate(FromNode, AssignEdge.Other, State, ReachSet, WorkList);
  };
  auto NextRevAssignState = [&](MatchState State) {
    for (const auto &RevAssignEdge : NodeInfo->ReverseEdges)
      propagate(FromNode, RevAssignEdge.Other, State, ReachSet, WorkList);
  };
  auto NextMemState = [&](MatchState State) {
    if (auto AliasSet = MemSet.getMemoryAliases(ToNode)) {
      for (const auto &MemAlias : *AliasSet)
        propagate(FromNode, MemAlias, State, ReachSet, WorkList);
    }
  };

  switch (Item.State) {
  case MatchState::FlowFromReadOnly: {
    NextRevAssignState(MatchState::FlowFromReadOnly);
    NextAssignState(MatchState::FlowToReadWrite);
    NextMemState(MatchState::FlowFromMemAliasReadOnly);
    break;
  }
  case MatchState::FlowFromMemAliasNoReadWrite: {
    NextRevAssignState(MatchState::FlowFromReadOnly);
    NextAssignState(MatchState::FlowToWriteOnly);
    break;
  }
  case MatchState::FlowFromMemAliasReadOnly: {
    NextRevAssignState(MatchState::FlowFromReadOnly);
    NextAssignState(MatchState::FlowToReadWrite);
    break;
  }
  case MatchState::FlowToWriteOnly: {
    NextAssignState(MatchState::FlowToWriteOnly);
    NextMemState(MatchState::FlowToMemAliasWriteOnly);
    break;
  }
  case MatchState::FlowToReadWrite: {
    NextAssignState(MatchState::FlowToReadWrite);
    NextMemState(MatchState::FlowToMemAliasReadWrite);
    break;
  }
  case MatchState::FlowToMemAliasWriteOnly: {
    NextAssignState(MatchState::FlowToWriteOnly);
    break;
  }
  case MatchState::FlowToMemAliasReadWrite: {
    NextAssignState(MatchState::FlowToReadWrite);
    break;
  }
  }
}

static AliasAttrMap buildAttrMap(const CFLGraph &Graph,
                                 const ReachabilitySet &ReachSet) {
  AliasAttrMap AttrMap;
  std::vector<InstantiatedValue> WorkList, NextList;

  // Initialize each node with its original AliasAttrs in CFLGraph
  for (const auto &Mapping : Graph.value_mappings()) {
    auto Val = Mapping.first;
    auto &ValueInfo = Mapping.second;
    for (unsigned I = 0, E = ValueInfo.getNumLevels(); I < E; ++I) {
      auto Node = InstantiatedValue{Val, I};
      AttrMap.add(Node, ValueInfo.getNodeInfoAtLevel(I).Attr);
      WorkList.push_back(Node);
    }
  }

  while (!WorkList.empty()) {
    for (const auto &Dst : WorkList) {
      auto DstAttr = AttrMap.getAttrs(Dst);
      if (DstAttr.none())
        continue;

      // Propagate attr on the same level
      for (const auto &Mapping : ReachSet.reachableValueAliases(Dst)) {
        auto Src = Mapping.first;
        if (AttrMap.add(Src, DstAttr))
          NextList.push_back(Src);
      }

      // Propagate attr to the levels below
      auto DstBelow = getNodeBelow(Graph, Dst);
      while (DstBelow) {
        if (AttrMap.add(*DstBelow, DstAttr)) {
          NextList.push_back(*DstBelow);
          break;
        }
        DstBelow = getNodeBelow(Graph, *DstBelow);
      }
    }
    WorkList.swap(NextList);
    NextList.clear();
  }

  return AttrMap;
}

CFLAndersAAResult::FunctionInfo
CFLAndersAAResult::buildInfoFrom(const Function &Fn) {
  CFLGraphBuilder<CFLAndersAAResult> GraphBuilder(
      *this, TLI,
      // Cast away the constness here due to GraphBuilder's API requirement
      const_cast<Function &>(Fn));
  auto &Graph = GraphBuilder.getCFLGraph();

  ReachabilitySet ReachSet;
  AliasMemSet MemSet;

  std::vector<WorkListItem> WorkList, NextList;
  initializeWorkList(WorkList, ReachSet, Graph);
  // TODO: make sure we don't stop before the fix point is reached
  while (!WorkList.empty()) {
    for (const auto &Item : WorkList)
      processWorkListItem(Item, Graph, ReachSet, MemSet, NextList);

    NextList.swap(WorkList);
    NextList.clear();
  }

  // Now that we have all the reachability info, propagate AliasAttrs according
  // to it
  auto IValueAttrMap = buildAttrMap(Graph, ReachSet);

  return FunctionInfo(Fn, GraphBuilder.getReturnValues(), ReachSet,
                      std::move(IValueAttrMap));
}

void CFLAndersAAResult::scan(const Function &Fn) {
  auto InsertPair = Cache.insert(std::make_pair(&Fn, Optional<FunctionInfo>()));
  (void)InsertPair;
  assert(InsertPair.second &&
         "Trying to scan a function that has already been cached");

  // Note that we can't do Cache[Fn] = buildSetsFrom(Fn) here: the function call
  // may get evaluated after operator[], potentially triggering a DenseMap
  // resize and invalidating the reference returned by operator[]
  auto FunInfo = buildInfoFrom(Fn);
  Cache[&Fn] = std::move(FunInfo);
  Handles.push_front(FunctionHandle(const_cast<Function *>(&Fn), this));
}

void CFLAndersAAResult::evict(const Function &Fn) { Cache.erase(&Fn); }

const Optional<CFLAndersAAResult::FunctionInfo> &
CFLAndersAAResult::ensureCached(const Function &Fn) {
  auto Iter = Cache.find(&Fn);
  if (Iter == Cache.end()) {
    scan(Fn);
    Iter = Cache.find(&Fn);
    assert(Iter != Cache.end());
    assert(Iter->second.hasValue());
  }
  return Iter->second;
}

const AliasSummary *CFLAndersAAResult::getAliasSummary(const Function &Fn) {
  auto &FunInfo = ensureCached(Fn);
  if (FunInfo.hasValue())
    return &FunInfo->getAliasSummary();
  else
    return nullptr;
}

AliasResult CFLAndersAAResult::query(const MemoryLocation &LocA,
                                     const MemoryLocation &LocB) {
  auto *ValA = LocA.Ptr;
  auto *ValB = LocB.Ptr;

  if (!ValA->getType()->isPointerTy() || !ValB->getType()->isPointerTy())
    return NoAlias;

  auto *Fn = parentFunctionOfValue(ValA);
  if (!Fn) {
    Fn = parentFunctionOfValue(ValB);
    if (!Fn) {
      // The only times this is known to happen are when globals + InlineAsm are
      // involved
      DEBUG(dbgs()
            << "CFLAndersAA: could not extract parent function information.\n");
      return MayAlias;
    }
  } else {
    assert(!parentFunctionOfValue(ValB) || parentFunctionOfValue(ValB) == Fn);
  }

  assert(Fn != nullptr);
  auto &FunInfo = ensureCached(*Fn);

  // AliasMap lookup
  if (FunInfo->mayAlias(ValA, LocA.Size, ValB, LocB.Size))
    return MayAlias;
  return NoAlias;
}

AliasResult CFLAndersAAResult::alias(const MemoryLocation &LocA,
                                     const MemoryLocation &LocB) {
  if (LocA.Ptr == LocB.Ptr)
    return LocA.Size == LocB.Size ? MustAlias : PartialAlias;

  // Comparisons between global variables and other constants should be
  // handled by BasicAA.
  // CFLAndersAA may report NoAlias when comparing a GlobalValue and
  // ConstantExpr, but every query needs to have at least one Value tied to a
  // Function, and neither GlobalValues nor ConstantExprs are.
  if (isa<Constant>(LocA.Ptr) && isa<Constant>(LocB.Ptr))
    return AAResultBase::alias(LocA, LocB);

  AliasResult QueryResult = query(LocA, LocB);
  if (QueryResult == MayAlias)
    return AAResultBase::alias(LocA, LocB);

  return QueryResult;
}

AnalysisKey CFLAndersAA::Key;

CFLAndersAAResult CFLAndersAA::run(Function &F, FunctionAnalysisManager &AM) {
  return CFLAndersAAResult(AM.getResult<TargetLibraryAnalysis>(F));
}

char CFLAndersAAWrapperPass::ID = 0;
INITIALIZE_PASS(CFLAndersAAWrapperPass, "cfl-anders-aa",
                "Inclusion-Based CFL Alias Analysis", false, true)

ImmutablePass *llvm::createCFLAndersAAWrapperPass() {
  return new CFLAndersAAWrapperPass();
}

CFLAndersAAWrapperPass::CFLAndersAAWrapperPass() : ImmutablePass(ID) {
  initializeCFLAndersAAWrapperPassPass(*PassRegistry::getPassRegistry());
}

void CFLAndersAAWrapperPass::initializePass() {
  auto &TLIWP = getAnalysis<TargetLibraryInfoWrapperPass>();
  Result.reset(new CFLAndersAAResult(TLIWP.getTLI()));
}

void CFLAndersAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.setPreservesAll();
  AU.addRequired<TargetLibraryInfoWrapperPass>();
}


text:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package erp.mod.fin.db;

/**
 *
 * @author Sergio Flores
 */
public enum SFinConceptEvaluation {
    NUMBER_CHECK,
    NUMBER_DPS,
    BIZ_PARTNER
}

redpajama_set_name: RedPajamaGithub


text:
namespace content {

CONTENT_EXPORT void BindInterfaceInGpuProcess(
    const std::string& interface_name,
    mojo::ScopedMessagePipeHandle interface_pipe);

// Bind to an interface exposed by the GPU process. The mojo interface must be
// marked with a [ServiceSandbox=sandbox.mojom.Sandbox.kGpu] attribute.
template <typename Interface>
void BindInterfaceInGpuProcess(mojo::PendingReceiver<Interface> receiver) {
  using ProvidedSandboxType = decltype(Interface::kServiceSandbox);
  static_assert(
      std::is_same<ProvidedSandboxType, const sandbox::mojom::Sandbox>::value,
      "This interface does not declare a proper ServiceSandbox attribute. "
      "See //docs/mojo_and_services.md (Specifying a sandbox).");
  static_assert(Interface::kServiceSandbox == sandbox::mojom::Sandbox::kGpu,
                "This interface must have [ServiceSandbox=kGpu].");

  BindInterfaceInGpuProcess(Interface::Name_, receiver.PassPipe());
}

}  // namespace content

#endif  // CONTENT_PUBLIC_BROWSER_GPU_SERVICE_REGISTRY_H_


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
Rev. Bryol. Lichénol. 31(3-4): 256-257 (1963)

#### Original name
Lecanora follmannii Klem.

### Remarks
null


text:
package play.learn.java.design.interpreter;

public class PlusExpression extends Expression {

	private Expression leftExpression;
	private Expression rightExpression;

	public PlusExpression(Expression leftExpression, Expression rightExpression) {
		this.leftExpression = leftExpression;
		this.rightExpression = rightExpression;
	}

	@Override
	public int interpret() {
		return leftExpression.interpret() + rightExpression.interpret();
	}

	@Override
	public String toString() {
		return "+";
	}

}


text:
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Character manipulation.
//!
//! For more details, see ::unicode::char (a.k.a. std::char)

#![allow(non_snake_case)]
#![doc(primitive = "char")]

use iter::Iterator;
use mem::transmute;
use option::Option::{None, Some};
use option::Option;
use slice::SliceExt;

// UTF-8 ranges and tags for encoding characters
static TAG_CONT: u8    = 0b1000_0000u8;
static TAG_TWO_B: u8   = 0b1100_0000u8;
static TAG_THREE_B: u8 = 0b1110_0000u8;
static TAG_FOUR_B: u8  = 0b1111_0000u8;
static MAX_ONE_B: u32   =     0x80u32;
static MAX_TWO_B: u32   =    0x800u32;
static MAX_THREE_B: u32 =  0x10000u32;

/*
    Lu  Uppercase_Letter        an uppercase letter
    Ll  Lowercase_Letter        a lowercase letter
    Lt  Titlecase_Letter        a digraphic character, with first part uppercase
    Lm  Modifier_Letter         a modifier letter
    Lo  Other_Letter            other letters, including syllables and ideographs
    Mn  Nonspacing_Mark         a nonspacing combining mark (zero advance width)
    Mc  Spacing_Mark            a spacing combining mark (positive advance width)
    Me  Enclosing_Mark          an enclosing combining mark
    Nd  Decimal_Number          a decimal digit
    Nl  Letter_Number           a letterlike numeric character
    No  Other_Number            a numeric character of other type
    Pc  Connector_Punctuation   a connecting punctuation mark, like a tie
    Pd  Dash_Punctuation        a dash or hyphen punctuation mark
    Ps  Open_Punctuation        an opening punctuation mark (of a pair)
    Pe  Close_Punctuation       a closing punctuation mark (of a pair)
    Pi  Initial_Punctuation     an initial quotation mark
    Pf  Final_Punctuation       a final quotation mark
    Po  Other_Punctuation       a punctuation mark of other type
    Sm  Math_Symbol             a symbol of primarily mathematical use
    Sc  Currency_Symbol         a currency sign
    Sk  Modifier_Symbol         a non-letterlike modifier symbol
    So  Other_Symbol            a symbol of other type
    Zs  Space_Separator         a space character (of various non-zero widths)
    Zl  Line_Separator          U+2028 LINE SEPARATOR only
    Zp  Paragraph_Separator     U+2029 PARAGRAPH SEPARATOR only
    Cc  Control                 a C0 or C1 control code
    Cf  Format                  a format control character
    Cs  Surrogate               a surrogate code point
    Co  Private_Use             a private-use character
    Cn  Unassigned              a reserved unassigned code point or a noncharacter
*/

/// The highest valid code point
#[stable]
pub const MAX: char = '\u{10ffff}';

/// Converts from `u32` to a `char`
#[inline]
#[stable]
pub fn from_u32(i: u32) -> Option<char> {
    // catch out-of-bounds and surrogates
    if (i > MAX as u32) || (i >= 0xD800 && i <= 0xDFFF) {
        None
    } else {
        Some(unsafe { transmute(i) })
    }
}

///
/// Converts a number to the character representing it
///
/// # Return value
///
/// Returns `Some(char)` if `num` represents one digit under `radix`,
/// using one character of `0-9` or `a-z`, or `None` if it doesn't.
///
/// # Panics
///
/// Panics if given an `radix` > 36.
///
#[inline]
#[unstable = "pending integer conventions"]
pub fn from_digit(num: uint, radix: uint) -> Option<char> {
    if radix > 36 {
        panic!("from_digit: radix is too high (maximum 36)");
    }
    if num < radix {
        unsafe {
            if num < 10 {
                Some(transmute(('0' as uint + num) as u32))
            } else {
                Some(transmute(('a' as uint + num - 10) as u32))
            }
        }
    } else {
        None
    }
}

/// Basic `char` manipulations.
#[stable]
pub trait CharExt {
    /// Checks if a `char` parses as a numeric digit in the given radix.
    ///
    /// Compared to `is_numeric()`, this function only recognizes the characters
    /// `0-9`, `a-z` and `A-Z`.
    ///
    /// # Return value
    ///
    /// Returns `true` if `c` is a valid digit under `radix`, and `false`
    /// otherwise.
    ///
    /// # Panics
    ///
    /// Panics if given a radix > 36.
    #[unstable = "pending integer conventions"]
    fn is_digit(self, radix: uint) -> bool;

    /// Converts a character to the corresponding digit.
    ///
    /// # Return value
    ///
    /// If `c` is between '0' and '9', the corresponding value between 0 and
    /// 9. If `c` is 'a' or 'A', 10. If `c` is 'b' or 'B', 11, etc. Returns
    /// none if the character does not refer to a digit in the given radix.
    ///
    /// # Panics
    ///
    /// Panics if given a radix outside the range [0..36].
    #[unstable = "pending integer conventions"]
    fn to_digit(self, radix: uint) -> Option<uint>;

    /// Returns an iterator that yields the hexadecimal Unicode escape
    /// of a character, as `char`s.
    ///
    /// All characters are escaped with Rust syntax of the form `\\u{NNNN}`
    /// where `NNNN` is the shortest hexadecimal representation of the code
    /// point.
    #[stable]
    fn escape_unicode(self) -> EscapeUnicode;

    /// Returns an iterator that yields the 'default' ASCII and
    /// C++11-like literal escape of a character, as `char`s.
    ///
    /// The default is chosen with a bias toward producing literals that are
    /// legal in a variety of languages, including C++11 and similar C-family
    /// languages. The exact rules are:
    ///
    /// * Tab, CR and LF are escaped as '\t', '\r' and '\n' respectively.
    /// * Single-quote, double-quote and backslash chars are backslash-
    ///   escaped.
    /// * Any other chars in the range [0x20,0x7e] are not escaped.
    /// * Any other chars are given hex Unicode escapes; see `escape_unicode`.
    #[stable]
    fn escape_default(self) -> EscapeDefault;

    /// Returns the amount of bytes this character would need if encoded in
    /// UTF-8.
    #[stable]
    fn len_utf8(self) -> uint;

    /// Returns the amount of bytes this character would need if encoded in
    /// UTF-16.
    #[stable]
    fn len_utf16(self) -> uint;

    /// Encodes this character as UTF-8 into the provided byte buffer,
    /// and then returns the number of bytes written.
    ///
    /// If the buffer is not large enough, nothing will be written into it
    /// and a `None` will be returned.
    #[stable]
    fn encode_utf8(self, dst: &mut [u8]) -> Option<uint>;

    /// Encodes this character as UTF-16 into the provided `u16` buffer,
    /// and then returns the number of `u16`s written.
    ///
    /// If the buffer is not large enough, nothing will be written into it
    /// and a `None` will be returned.
    #[stable]
    fn encode_utf16(self, dst: &mut [u16]) -> Option<uint>;
}

#[stable]
impl CharExt for char {
    #[unstable = "pending integer conventions"]
    fn is_digit(self, radix: uint) -> bool {
        self.to_digit(radix).is_some()
    }

    #[unstable = "pending integer conventions"]
    fn to_digit(self, radix: uint) -> Option<uint> {
        if radix > 36 {
            panic!("to_digit: radix is too high (maximum 36)");
        }
        let val = match self {
          '0' ... '9' => self as uint - ('0' as uint),
          'a' ... 'z' => self as uint + 10 - ('a' as uint),
          'A' ... 'Z' => self as uint + 10 - ('A' as uint),
          _ => return None,
        };
        if val < radix { Some(val) }
        else { None }
    }

    #[stable]
    fn escape_unicode(self) -> EscapeUnicode {
        EscapeUnicode { c: self, state: EscapeUnicodeState::Backslash }
    }

    #[stable]
    fn escape_default(self) -> EscapeDefault {
        let init_state = match self {
            '\t' => EscapeDefaultState::Backslash('t'),
            '\r' => EscapeDefaultState::Backslash('r'),
            '\n' => EscapeDefaultState::Backslash('n'),
            '\\' => EscapeDefaultState::Backslash('\\'),
            '\'' => EscapeDefaultState::Backslash('\''),
            '"'  => EscapeDefaultState::Backslash('"'),
            '\x20' ... '\x7e' => EscapeDefaultState::Char(self),
            _ => EscapeDefaultState::Unicode(self.escape_unicode())
        };
        EscapeDefault { state: init_state }
    }

    #[inline]
    #[stable]
    fn len_utf8(self) -> uint {
        let code = self as u32;
        match () {
            _ if code < MAX_ONE_B   => 1,
            _ if code < MAX_TWO_B   => 2,
            _ if code < MAX_THREE_B => 3,
            _  => 4,
        }
    }

    #[inline]
    #[stable]
    fn len_utf16(self) -> uint {
        let ch = self as u32;
        if (ch & 0xFFFF_u32) == ch { 1 } else { 2 }
    }

    #[inline]
    #[unstable = "pending decision about Iterator/Writer/Reader"]
    fn encode_utf8(self, dst: &mut [u8]) -> Option<uint> {
        encode_utf8_raw(self as u32, dst)
    }

    #[inline]
    #[unstable = "pending decision about Iterator/Writer/Reader"]
    fn encode_utf16(self, dst: &mut [u16]) -> Option<uint> {
        encode_utf16_raw(self as u32, dst)
    }
}

/// Encodes a raw u32 value as UTF-8 into the provided byte buffer,
/// and then returns the number of bytes written.
///
/// If the buffer is not large enough, nothing will be written into it
/// and a `None` will be returned.
#[inline]
#[unstable]
pub fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> Option<uint> {
    // Marked #[inline] to allow llvm optimizing it away
    if code < MAX_ONE_B && dst.len() >= 1 {
        dst[0] = code as u8;
        Some(1)
    } else if code < MAX_TWO_B && dst.len() >= 2 {
        dst[0] = (code >> 6u & 0x1F_u32) as u8 | TAG_TWO_B;
        dst[1] = (code & 0x3F_u32) as u8 | TAG_CONT;
        Some(2)
    } else if code < MAX_THREE_B && dst.len() >= 3  {
        dst[0] = (code >> 12u & 0x0F_u32) as u8 | TAG_THREE_B;
        dst[1] = (code >>  6u & 0x3F_u32) as u8 | TAG_CONT;
        dst[2] = (code & 0x3F_u32) as u8 | TAG_CONT;
        Some(3)
    } else if dst.len() >= 4 {
        dst[0] = (code >> 18u & 0x07_u32) as u8 | TAG_FOUR_B;
        dst[1] = (code >> 12u & 0x3F_u32) as u8 | TAG_CONT;
        dst[2] = (code >>  6u & 0x3F_u32) as u8 | TAG_CONT;
        dst[3] = (code & 0x3F_u32) as u8 | TAG_CONT;
        Some(4)
    } else {
        None
    }
}

/// Encodes a raw u32 value as UTF-16 into the provided `u16` buffer,
/// and then returns the number of `u16`s written.
///
/// If the buffer is not large enough, nothing will be written into it
/// and a `None` will be returned.
#[inline]
#[unstable]
pub fn encode_utf16_raw(mut ch: u32, dst: &mut [u16]) -> Option<uint> {
    // Marked #[inline] to allow llvm optimizing it away
    if (ch & 0xFFFF_u32) == ch  && dst.len() >= 1 {
        // The BMP falls through (assuming non-surrogate, as it should)
        dst[0] = ch as u16;
        Some(1)
    } else if dst.len() >= 2 {
        // Supplementary planes break into surrogates.
        ch -= 0x1_0000_u32;
        dst[0] = 0xD800_u16 | ((ch >> 10) as u16);
        dst[1] = 0xDC00_u16 | ((ch as u16) & 0x3FF_u16);
        Some(2)
    } else {
        None
    }
}

/// An iterator over the characters that represent a `char`, as escaped by
/// Rust's unicode escaping rules.
#[derive(Clone)]
#[stable]
pub struct EscapeUnicode {
    c: char,
    state: EscapeUnicodeState
}

#[derive(Clone)]
#[unstable]
enum EscapeUnicodeState {
    Backslash,
    Type,
    LeftBrace,
    Value(uint),
    RightBrace,
    Done,
}

#[stable]
impl Iterator for EscapeUnicode {
    type Item = char;

    fn next(&mut self) -> Option<char> {
        match self.state {
            EscapeUnicodeState::Backslash => {
                self.state = EscapeUnicodeState::Type;
                Some('\\')
            }
            EscapeUnicodeState::Type => {
                self.state = EscapeUnicodeState::LeftBrace;
                Some('u')
            }
            EscapeUnicodeState::LeftBrace => {
                let mut n = 0;
                while (self.c as u32) >> (4 * (n + 1)) != 0 {
                    n += 1;
                }
                self.state = EscapeUnicodeState::Value(n);
                Some('{')
            }
            EscapeUnicodeState::Value(offset) => {
                let v = match ((self.c as i32) >> (offset * 4)) & 0xf {
                    i @ 0 ... 9 => '0' as i32 + i,
                    i => 'a' as i32 + (i - 10)
                };
                if offset == 0 {
                    self.state = EscapeUnicodeState::RightBrace;
                } else {
                    self.state = EscapeUnicodeState::Value(offset - 1);
                }
                Some(unsafe { transmute(v) })
            }
            EscapeUnicodeState::RightBrace => {
                self.state = EscapeUnicodeState::Done;
                Some('}')
            }
            EscapeUnicodeState::Done => None,
        }
    }
}

/// An iterator over the characters that represent a `char`, escaped
/// for maximum portability.
#[derive(Clone)]
#[stable]
pub struct EscapeDefault {
    state: EscapeDefaultState
}

#[derive(Clone)]
#[unstable]
enum EscapeDefaultState {
    Backslash(char),
    Char(char),
    Done,
    Unicode(EscapeUnicode),
}

#[stable]
impl Iterator for EscapeDefault {
    type Item = char;

    fn next(&mut self) -> Option<char> {
        match self.state {
            EscapeDefaultState::Backslash(c) => {
                self.state = EscapeDefaultState::Char(c);
                Some('\\')
            }
            EscapeDefaultState::Char(c) => {
                self.state = EscapeDefaultState::Done;
                Some(c)
            }
            EscapeDefaultState::Done => None,
            EscapeDefaultState::Unicode(ref mut iter) => iter.next()
        }
    }
}


text:
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.

using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Web.Razor.Editor;
using System.Web.Razor.Generator;
using System.Web.Razor.Text;
using System.Web.Razor.Tokenizer.Symbols;
using Microsoft.Internal.Web.Utils;

namespace System.Web.Razor.Parser.SyntaxTree
{
    public class Span : SyntaxTreeNode
    {
        private SourceLocation _start;

        public Span(SpanBuilder builder)
        {
            ReplaceWith(builder);
        }

        public SpanKind Kind { get; protected set; }
        public IEnumerable<ISymbol> Symbols { get; protected set; }

        // Allow test code to re-link spans
        public Span Previous { get; protected internal set; }
        public Span Next { get; protected internal set; }

        public SpanEditHandler EditHandler { get; protected set; }
        public ISpanCodeGenerator CodeGenerator { get; protected set; }

        public override bool IsBlock
        {
            get { return false; }
        }

        public override int Length
        {
            get { return Content.Length; }
        }

        public override SourceLocation Start
        {
            get { return _start; }
        }

        public string Content { get; private set; }

        public void Change(Action<SpanBuilder> changes)
        {
            SpanBuilder builder = new SpanBuilder(this);
            changes(builder);
            ReplaceWith(builder);
        }

        public void ReplaceWith(SpanBuilder builder)
        {
            Debug.Assert(!builder.Symbols.Any() || builder.Symbols.All(s => s != null));

            Kind = builder.Kind;
            Symbols = builder.Symbols;
            EditHandler = builder.EditHandler;
            CodeGenerator = builder.CodeGenerator ?? SpanCodeGenerator.Null;
            _start = builder.Start;

            // Since we took references to the values in SpanBuilder, clear its references out
            builder.Reset();

            // Calculate other properties
            Content = Symbols.Aggregate(new StringBuilder(), (sb, sym) => sb.Append(sym.Content), sb => sb.ToString());
        }

        /// <summary>
        /// Accepts the specified visitor
        /// </summary>
        /// <remarks>
        /// Calls the VisitSpan method on the specified visitor, passing in this
        /// </remarks>
        public override void Accept(ParserVisitor visitor)
        {
            visitor.VisitSpan(this);
        }

        public override string ToString()
        {
            StringBuilder builder = new StringBuilder();
            builder.Append(Kind);
            builder.AppendFormat(" Span at {0}::{1} - [{2}]", Start, Length, Content);
            builder.Append(" Edit: <");
            builder.Append(EditHandler.ToString());
            builder.Append(">");
            builder.Append(" Gen: <");
            builder.Append(CodeGenerator.ToString());
            builder.Append("> {");
            builder.Append(String.Join(";", Symbols.GroupBy(sym => sym.GetType()).Select(grp => String.Concat(grp.Key.Name, ":", grp.Count()))));
            builder.Append("}");
            return builder.ToString();
        }

        public void ChangeStart(SourceLocation newStart)
        {
            _start = newStart;
            Span current = this;
            SourceLocationTracker tracker = new SourceLocationTracker(newStart);
            tracker.UpdateLocation(Content);
            while ((current = current.Next) != null)
            {
                current._start = tracker.CurrentLocation;
                tracker.UpdateLocation(current.Content);
            }
        }

        internal void SetStart(SourceLocation newStart)
        {
            _start = newStart;
        }

        /// <summary>
        /// Checks that the specified span is equivalent to the other in that it has the same start point and content.
        /// </summary>
        public override bool EquivalentTo(SyntaxTreeNode node)
        {
            Span other = node as Span;
            return other != null &&
                   Kind.Equals(other.Kind) &&
                   Start.Equals(other.Start) &&
                   EditHandler.Equals(other.EditHandler) &&
                   String.Equals(other.Content, Content, StringComparison.Ordinal);
        }

        public override bool Equals(object obj)
        {
            Span other = obj as Span;
            return other != null &&
                   Kind.Equals(other.Kind) &&
                   EditHandler.Equals(other.EditHandler) &&
                   CodeGenerator.Equals(other.CodeGenerator) &&
                   Symbols.SequenceEqual(other.Symbols);
        }

        public override int GetHashCode()
        {
            return HashCodeCombiner.Start()
                .Add((int)Kind)
                .Add(Start)
                .Add(Content)
                .CombinedHash;
        }
    }
}


text:
'use strict';

const electron = require('electron');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
const ApplyMenus = require('./main/menus-manager');

let mainWindow;

function createWindow () {

  mainWindow = new BrowserWindow({
    width: 600,
    height: 336,
    'titleBarStyle':'hidden-inset',
    resizable: false,
    y: 180,
    backgroundColor: '#E6F8F8F8'
  });

  mainWindow.loadURL('file://' + __dirname + '/index.html');

  mainWindow.webContents.openDevTools();

  mainWindow.on('closed', function() {
    mainWindow = null;
    app.quit();
  });

  //
  ApplyMenus();

}

app.on('ready', createWindow);

// Quit when all windows are closed.
app.on('window-all-closed', function () {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', function () {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (mainWindow === null) {
    createWindow();
  }
});


text:
TastyResource
=============

This AngularJS module is intended to be a lightweight handler for TastyPie's REST resources for Django. It tries to be similar to Angular's $resource in the ways it defines and retrieves resources.

TastyResource is written in CoffeeScript, but compiled versions will be included in the repository

Usage
=====

TastyResource makes no attempt to be generic in its handling of REST interfaces. Its sole focus on TastyPie makes usage and configuration a snap.

Below is an example program that defines a resource and uses it in a controller.

	app = angular.module("myapp", ["tastyResource"]);

	app.factory("User", ["TastyResource", function (TastyResource) {
		return TastyResource({
			url: "/api/v1/user/",
			cache: true
		});
	}]);

	app.controller("MyController", ["$scope", "User", function ($scope, User) {
		$scope.users = User.query();
		$scope.user = User.get(1);

		$scope.create = function() {
			user = User;
			user.firstname = "John";
			user.lastname = "Doe";
			user.post();
		}

		$scope.edit = function(){
			$scope.user.firstname = "Jane";
			$scope.user.lastname = "Doe";
			$scope.user.put();
		}
	}]);

Features
========

TastyResource also takes advantage of certain TastyPie features. Below are some examples of these features being used.

Filters
-------

Make use of the filter features on TastyPie by passing an object to the query function.

	user = User.query({ firstname: "Jane", lastname: "Doe" });

Relationships
-------------

Although TastyResource doesn't attempt to stub out URIs in the return resources, it does understand when trying to retrieve and save resource URIs.

	user = User.get(1);
	profile = Profile.get(user.profile);

	new_profile = Profile;
	new_profile.country = "Australia";
	new_profile.post();

	user.profile = new_profile;
	user.put();


text:
#ifndef _RHOAPPADAPTER_H_
#define _RHOAPPADAPTER_H_

#include "common/RhoStd.h"
#include "net/INetRequest.h"

namespace rho {
struct _CRhoAppAdapter {

static const int ERR_NONE = 0;
static const int ERR_NETWORK = 1;
static const int ERR_REMOTESERVER = 2;
static const int ERR_RUNTIME = 3;
static const int ERR_UNEXPECTEDSERVERRESPONSE = 4;
static const int ERR_DIFFDOMAINSINSYNCSRC = 5;
static const int ERR_NOSERVERRESPONSE = 6;
static const int ERR_CLIENTISNOTLOGGEDIN = 7;
static const int ERR_CUSTOMSYNCSERVER = 8;
static const int ERR_UNATHORIZED = 9;
static const int ERR_CANCELBYUSER = 10;
static const int ERR_SYNCVERSION = 11;
static const int ERR_GEOLOCATION = 12;

static String getMessageText(const char* szName);
static String getErrorText(int nError);
static int    getErrorFromResponse(NetResponse& resp);
static void   loadServerSources(const String& strSources);
static void   loadAllSyncSources();
static const char* getRhoDBVersion();
static void   resetDBOnSyncUserChanged();

};
extern const _CRhoAppAdapter& RhoAppAdapter;
}

#endif //_RHOAPPADAPTER_H_


text:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center_vertical" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_marginLeft="6dp"
        android:layout_below="@+id/layout_top" >

        <TextView
            android:id="@+id/tv_line_one"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:singleLine="true"
            android:text="type"
            android:textSize="17sp" />

        <ImageView
            android:id="@+id/iv_icon"
            android:layout_width="25dp"
            android:layout_height="25dp"
            android:layout_centerVertical="true"
            android:layout_toLeftOf="@+id/tv_line_one"
            android:layout_marginRight="6dp"
            android:scaleType="centerCrop"
            android:src="@drawable/logo" />

    </RelativeLayout>

</RelativeLayout>


text:
using namespace BrainCloud;

TEST_F(TestBCDataStream, CustomPageEvent)
{
    TestResult tr;

    Json::Value eventProperties;
    eventProperties["testProperty"] = "1";

    Json::FastWriter fw;
    std::string strProps = fw.write(eventProperties);
    m_bc->getDataStreamService()->customPageEvent("testPage", strProps.c_str(), &tr);
    tr.run(m_bc);
}

TEST_F(TestBCDataStream, CustomScreenEvent)
{
    TestResult tr;

    Json::Value eventProperties;
    eventProperties["testProperty"] = "1";

    Json::FastWriter fw;
    std::string strProps = fw.write(eventProperties);
    m_bc->getDataStreamService()->customScreenEvent("testScreen", strProps.c_str(), &tr);
    tr.run(m_bc);
}

TEST_F(TestBCDataStream, CustomTrackEvent)
{
    TestResult tr;

    Json::Value eventProperties;
    eventProperties["testProperty"] = "1";

    Json::FastWriter fw;
    std::string strProps = fw.write(eventProperties);
    m_bc->getDataStreamService()->customTrackEvent("testTrack", strProps.c_str(), &tr);
    tr.run(m_bc);
}

TEST_F(TestBCDataStream, SubmitCrashReport)
{
    TestResult tr;
    m_bc->getDataStreamService()->submitCrashReport("test", "test", "{\"testReport\": \"Testing\"}", "test", "test", "test", "test", true, &tr);
    tr.run(m_bc);
}


text:
from threading import Lock
from deterministic_encryption_utils.encryption.VirtualFile import VirtualFile

class FileHandleContainer(object):

    def __init__(self):
        self.handles = dict()
        self.freeIndices = list()
        self.lock = Lock()

    def registerHandle(self, path, flags):
        with self.lock:
            fileHandleObject = VirtualFile(path, flags)
            fileHandleIndex = self.__getNextFreeIndex()
            self.handles[fileHandleIndex] = fileHandleObject
            return fileHandleIndex

    def getHandle(self, index):
        with self.lock:
            if index not in self.handles.keys():
                raise ValueError('The given index "{0}" is not valid.'.format(index))
            return self.handles[index]

    def unregisterHandle(self, index):
        if index is 0:
            return
        with self.lock:
            if index not in self.handles.keys():
                raise ValueError('The given index "{0}" is not valid.'.format(index))
            self.freeIndices.append(index)
            handleObject = self.handles.pop(index)
            handleObject.closeFileHandle()

    def __getNextFreeIndex(self):
        if len(self.freeIndices) > 0:
            return self.freeIndices.pop()
        return len(self.handles) + 1 # 0 is a special handle


text:
<?php
$path = dirname(__FILE__) . '/';
include_once $path . 'F1OAuth/AppConfig.php';
include_once $path . 'includes/db_client.php';
include_once $path . 'includes/session.php';

// Get form selections and currently saved groups
$db = new DB_Access();
$currentGroups = array();
$churchid = 0;

$sess = new Session();

if(isset($_SESSION['churchid'])) {
    $churchid = $_SESSION['churchid'];
    $currentGroups = $db->FetchFacebookGroups($churchid);
}
else {
    error_log(__FILE__ . ': ChurchID not set in session');
    echo 'No ChurchID?';
    //echo '<fb:redirect url="'. AppConfig::$app_url . '" />';
}

$groupSelections = $_POST['adminGroups'];
$groupsToDelete = array();
$groupsToSave = array();

// Save form selections
foreach($currentGroups as $group) {
    // if in $currentGroups but not in $groupSelections => delete
    $$foundGroupKey = array_search($group, $groupSelections);
    if($$foundGroupKey === false) {
        $groupsToDelete[] = $group;
    }
    else {  // Found the group, so just remove the group from the list of groups to insert
        unset($groupSelections[$$foundGroupKey]);
    }
}

if(count($groupsToDelete) > 0) {
    echo 'DeleteFacebookGroups called; NumGroups: ' . count($groupsToDelete) . '
';
    $db->DeleteFacebookGroups($churchid, $groupsToDelete);
}

if(count($groupSelections) > 0) {
    echo 'SaveFacebookGroups called; NumGroups: ' . count($groupSelections) . '
';
    $db->SaveFacebookGroups($churchid, $groupSelections);
}

//if (count($groupSelections) > 0) {
//    echo 'My Groups:
';
//    foreach($groupSelections as $groupID){
//        echo $groupID . '
';
//    }
//}

// Redirect to index page
echo '<fb:redirect url="'. AppConfig::$app_url . '" />';
?>

<fb:success>
     <fb:message>Success message</fb:message>
     This is the success message text.
</fb:success>


text:
<?php

namespace Zerg\CallsBundle\Entity;

use Doctrine\ORM\EntityRepository;

/**
 * TicketRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class TicketRepository extends EntityRepository
{
}


text:
document.onkeypress = checkKey;

function eventFire(el, etype){
  if (el.fireEvent) {
    el.fireEvent('on' + etype);
  } else {
    var evObj = document.createEvent('Events');
    evObj.initEvent(etype, true, false);
    el.dispatchEvent(evObj);
  }
}

function checkKey(e) {
    e = e || window.event;
    if (e.charCode == 32) {
      eventFire(document.getElementById('buttonPlay'), 'click');
    } else if(e.ctrlKey && e.keyCode == 37) {
      eventFire(document.getElementById('buttonPrev'), 'mousedown');
      eventFire(document.getElementById('buttonPrev'), 'mouseup');
    } else if(e.ctrlKey && e.keyCode == 39) {
      eventFire(document.getElementById('buttonNext'), 'mousedown');
      eventFire(document.getElementById('buttonNext'), 'mouseup');
    }
}


text:
using System.Globalization;

namespace Framework
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;

    /// <summary>
    /// Enum Extensions.
    /// </summary>
    public static class EnumExtensions
    {
        ///-------------------------------------------------------------------------------------------------
        /// <summary>
        ///     A Type extension method that enum to list.
        /// </summary>
        ///
        /// <param name="enumType">
        ///     The enumType to act on.
        /// </param>
        /// <param name="skipValues">
        ///     A variable-length parameters list containing skip values.
        /// </param>
        ///
        /// <returns>
        ///     A list of.
        /// </returns>
        ///-------------------------------------------------------------------------------------------------
        public static ICollection<Pair<string, long>> EnumToList(this Type enumType, params long[] skipValues)
        {
            Array values = Enum.GetValues(enumType);
            List<Pair<string, long>> list = new List<Pair<string, long>>();
            List<long> skipList = new List<long>();

            if (skipValues != null)
            {
                skipList.AddRange(skipValues);
            }

            foreach (Enum @enum in values)
            {
                var value = Convert.ToInt32(@enum.ToString("D"));

                if (!skipList.Contains(value))
                {
                    list.Add(new Pair<string, long>(@enum.ToLocalizedDescription(), value));
                }
            }
            return list;
        }

        private static void CheckIsEnum<T>(bool withFlags)
        {
            var enumType = typeof(T);
            var isNullableType = enumType.IsNullableType();
            Type type = isNullableType ? Nullable.GetUnderlyingType(enumType) : enumType;

            if (!type.IsEnum)
                throw new ArgumentException(string.Format("Type '{0}' is not an enum", typeof(T).FullName));
            if (withFlags && !Attribute.IsDefined(type, typeof(FlagsAttribute)))
                throw new ArgumentException(string.Format("Type '{0}' doesn't have the 'Flags' attribute", type.FullName));
        }

        ///-------------------------------------------------------------------------------------------------
        /// <summary>
        ///     A T extension method that query if 'value' is flag set.
        /// </summary>
        ///
        /// <remarks>
        ///     Anwar Javed, 09/16/2013 1:47 PM.
        /// </remarks>
        ///
        /// <typeparam name="T">
        ///     Generic type parameter.
        /// </typeparam>
        /// <param name="value">
        ///     The value.
        /// </param>
        /// <param name="flag">
        ///     The flag.
        /// </param>
        ///
        /// <returns>
        ///     true if flag set< t>, false if not.
        /// </returns>
        ///-------------------------------------------------------------------------------------------------
        public static bool IsFlagSet<T>(this T value, T flag) where T : struct
        {
            CheckIsEnum<T>(true);

            long lValue = Convert.ToInt64(value);
            long lFlag = Convert.ToInt64(flag);
            return (lValue & lFlag) == lFlag;
        }

        public static IEnumerable<T> GetFlags<T>(this T value) where T : struct
        {
            CheckIsEnum<T>(true);
            return Enum.GetValues(typeof(T)).Cast<T>().Where(flag => value.IsFlagSet(flag));
        }

        public static T ClearFlags<T>(this T value, T flags) where T : struct
        {
            return value.SetFlags(flags, false);
        }

        public static T SetFlags<T>(this T value, T flags) where T : struct
        {
            return value.SetFlags(flags, true);
        }

        public static T SetFlags<T>(this T value, T flags, bool on) where T : struct
        {
            CheckIsEnum<T>(true);
            long lValue = Convert.ToInt64(value);
            long lFlag = Convert.ToInt64(flags);
            if (on)
            {
                lValue |= lFlag;
            }
            else
            {
                lValue &= (~lFlag);
            }
            return (T)Enum.ToObject(typeof(T), lValue);
        }

        ///-------------------------------------------------------------------------------------------------
        /// <summary>
        ///     An IEnumerable<T> extension method that combine flags.
        /// </summary>
        ///
        /// <remarks>
        ///     Anwar Javed, 09/16/2013 1:47 PM.
        /// </remarks>
        ///
        /// <typeparam name="T">
        ///     Generic type parameter.
        /// </typeparam>
        /// <param name="flags">
        ///     The flags to act on.
        /// </param>
        ///
        /// <returns>
        ///     .
        /// </returns>
        ///-------------------------------------------------------------------------------------------------
        public static T CombineFlags<T>(this IEnumerable<T> flags) where T : struct
        {
            CheckIsEnum<T>(true);
            long lValue = flags.Select(flag => Convert.ToInt64(flag)).Aggregate<long, long>(0, (current, lFlag) => current | lFlag);
            return (T)Enum.ToObject(typeof(T), lValue);
        }

        ///-------------------------------------------------------------------------------------------------
        /// <summary>
        ///     A Type extension method that enum to dictionary.
        /// </summary>
        ///
        /// <param name="enumType">
        ///     The enumType to act on.
        /// </param>
        /// <param name="skipValues">
        ///     A variable-length parameters list containing skip values.
        /// </param>
        ///
        /// <returns>
        ///     .
        /// </returns>
        ///-------------------------------------------------------------------------------------------------
        public static IDictionary<string, long> EnumToDictionary(this Type enumType, params long[] skipValues)
        {
            Array values = Enum.GetValues(enumType);
            IDictionary<string, long> dictionary = new Dictionary<string, long>(StringComparer.OrdinalIgnoreCase);
            List<long> skipList = new List<long>();

            if (skipValues != null)
            {
                skipList.AddRange(skipValues);
            }

            foreach (Enum @enum in values)
            {
                var value = Convert.ToInt32(@enum.ToString("D"));

                if (!skipList.Contains(value))
                {
                    dictionary.Add(@enum.ToLocalizedDescription(), value);
                }
            }
            return dictionary;
        }

        ///-------------------------------------------------------------------------------------------------
        /// <summary>
        ///     A Type extension method that enum to dictionary.
        /// </summary>
        ///
        /// <param name="enumType">
        ///     The enumType to act on.
        /// </param>
        /// <param name="skipValues">
        ///     A variable-length parameters list containing skip values.
        /// </param>
        ///
        /// <returns>
        ///     .
        /// </returns>
        ///-------------------------------------------------------------------------------------------------
        public static IDictionary<string, long> EnumToDictionaryValues(this Type enumType, params long[] skipValues)
        {
            Array values = Enum.GetValues(enumType);
            IDictionary<string, long> dictionary = new Dictionary<string, long>(StringComparer.OrdinalIgnoreCase);
            List<long> skipList = new List<long>();

            if (skipValues != null)
            {
                skipList.AddRange(skipValues);
            }

            foreach (Enum @enum in values)
            {
                var value = Convert.ToInt32(@enum.ToString("D"));

                if (!skipList.Contains(value))
                {
                    dictionary.Add(@enum.ToString("G"), value);
                }
            }
            return dictionary;
        }

        /// <summary>
        /// Toes the description.
        /// </summary>
        /// <param name="enumeration">The enumeration.</param>
        /// <returns>DEscription of Current Enum.</returns>
        public static string ToDescription(this Enum enumeration)
        {
            // Get the type
            Type type = enumeration.GetType();

            // Get fieldinfo for this type
            FieldInfo fieldInfo = type.GetField(enumeration.ToString());

            // Get the stringvalue attributes.
            if (fieldInfo != null)
            {
                System.ComponentModel.DescriptionAttribute attribs =
                    (from attr in fieldInfo.GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute), false) select attr).Cast<System.ComponentModel.DescriptionAttribute>().FirstOrDefault();

                // Return the first if there was a match.
                if (attribs != null)
                {
                    if (!string.IsNullOrWhiteSpace(attribs.Description))
                    {
                        return attribs.Description;
                    }
                }

                return enumeration.ToString("G");
            }

            return null;
        }

        ///-------------------------------------------------------------------------------------------------
        /// <summary>
        ///     An Enum extension method that converts an enumeration to a localized description.
        /// </summary>
        ///
        /// <param name="enumeration">
        ///     The enumeration.
        /// </param>
        ///
        /// <returns>
        ///     enumeration as a string.
        /// </returns>
        ///-------------------------------------------------------------------------------------------------
        public static string ToLocalizedDescription(this Enum enumeration)
        {
            // Get the type
            Type type = enumeration.GetType();

            // Get fieldinfo for this type
            FieldInfo fieldInfo = type.GetField(enumeration.ToString());

            // Get the stringvalue attributes
            DescriptionAttribute attribs =
              (from attr in fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false) select attr).Cast<DescriptionAttribute>().FirstOrDefault();

            // Return the first if there was a match.
            if (attribs != null)
            {
                string desc = attribs.GetLocalizedDescription(CultureInfo.CurrentUICulture);
                if (!string.IsNullOrWhiteSpace(desc))
                {
                    return desc;
                }
            }
            else
            {
                System.ComponentModel.DescriptionAttribute descriptionAttribute =
             (from attr in fieldInfo.GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute), false) select attr).Cast<System.ComponentModel.DescriptionAttribute>().FirstOrDefault();

                // Return the first if there was a match.
                if (descriptionAttribute != null)
                {
                    string desc = descriptionAttribute.Description;
                    if (!string.IsNullOrWhiteSpace(desc))
                    {
                        return desc;
                    }
                }
            }

            return enumeration.ToString("G");
        }

        ///-------------------------------------------------------------------------------------------------
        /// <summary>
        ///     An Enum extension method that gets the attributes.
        /// </summary>
        ///
        /// <typeparam name="T">
        ///     Generic type parameter.
        /// </typeparam>
        /// <param name="enumeration">
        ///     The enumeration.
        /// </param>
        /// <param name="inherit">
        ///     (optional) the inherit.
        /// </param>
        ///
        /// <returns>
        ///     The attributes< t>
        /// </returns>
        ///-------------------------------------------------------------------------------------------------
        public static IReadOnlyList<T> GetAttributes<T>(this Enum enumeration, bool inherit = false) where T : Attribute
        {
            Type type = enumeration.GetType();
            FieldInfo fieldInfo = type.GetField(enumeration.ToString());
            return fieldInfo.GetCustomAttributes(typeof(T), inherit).OfType<T>().ToList();
        }

        ///-------------------------------------------------------------------------------------------------
        /// <summary>
        ///     An Enum extension method that gets an attribute.
        /// </summary>
        ///
        /// <typeparam name="T">
        ///     Generic type parameter.
        /// </typeparam>
        /// <param name="enumeration">
        ///     The enumeration.
        /// </param>
        /// <param name="inherit">
        ///     (optional) the inherit.
        /// </param>
        ///
        /// <returns>
        ///     The attribute< t>
        /// </returns>
        ///-------------------------------------------------------------------------------------------------
        public static T GetAttribute<T>(this Enum enumeration, bool inherit = false) where T : Attribute
        {
            return enumeration.GetAttributes<T>(inherit).FirstOrDefault();
        }

        ///-------------------------------------------------------------------------------------------------
        /// <summary>
        ///     A Type extension method that parse enum.
        /// </summary>
        ///
        /// <param name="enumType">
        ///     The enumType to act on.
        /// </param>
        /// <param name="value">
        ///     The value.
        /// </param>
        ///
        /// <returns>
        ///     .
        /// </returns>
        ///-------------------------------------------------------------------------------------------------
        public static object ParseEnum(this Type enumType, string value)
        {
            var isNullableType = enumType.IsNullableType();
            Type type = isNullableType ? Nullable.GetUnderlyingType(enumType) : enumType;

            var pairs = type.EnumToDictionary();

            if (pairs.ContainsKey(value))
            {
                return Enum.Parse(type, pairs[value].ToString());
            }

            return Enum.Parse(type, value);
        }
    }
}


text:
package com.rampo.updatechecker;

import android.app.Activity;
import android.content.SharedPreferences;
import android.support.v4.app.FragmentActivity;

import com.rampo.updatechecker.notice.Dialog;
import com.rampo.updatechecker.notice.Notice;
import com.rampo.updatechecker.notice.Notification;
import com.rampo.updatechecker.store.Store;

/**
 * UpdateChecker is a class that can be used by Android Developers to increase the number of their apps' updates.
 *
 * @author Pietro Rampini (rampini.pietro@gmail.com)
 */
public class UpdateChecker implements ASyncCheckResult, UpdateCheckerResult {

    public static final String ROOT_PLAY_STORE_DEVICE = "market://details?id=";
    public static final String PREFS_FILENAME = "updateChecker";
    public static final String DONT_SHOW_AGAIN_PREF_KEY = "dontShow";
    private static final String SUCCESSFUL_CHEKS_PREF_KEY = "nLaunches";

    static Store DEFAULT_STORE = Store.GOOGLE_PLAY;
    static int DEFAULT_SUCCESSFUL_CHECKS_REQUIRED = 5;
    static int DEFAULT_NOTICE_ICON_RES_ID = 0;
    static Notice DEFAULT_NOTICE = Notice.DIALOG;

    static Activity mActivity;
    static Store mStore;
    static int mSuccessfulChecksRequired;
    static Notice mNotice;
    static int mNoticeIconResId;
    static UpdateCheckerResult mLibraryResultCallaback;
    static ASyncCheckResult mCheckResultCallback;
    static boolean mCustomImplementation;

    public UpdateChecker(Activity activity) {
        mActivity = activity;
        mStore = DEFAULT_STORE;
        mSuccessfulChecksRequired = DEFAULT_SUCCESSFUL_CHECKS_REQUIRED;
        mNotice = DEFAULT_NOTICE;
        mNoticeIconResId = DEFAULT_NOTICE_ICON_RES_ID;
        mCheckResultCallback = this;
        mLibraryResultCallaback = this;
        mCustomImplementation = false;
    }

    public UpdateChecker(Activity activity, UpdateCheckerResult updateCheckerResult) {
        mActivity = activity;
        mStore = DEFAULT_STORE;
        mSuccessfulChecksRequired = DEFAULT_SUCCESSFUL_CHECKS_REQUIRED;
        mNotice = DEFAULT_NOTICE;
        mNoticeIconResId = DEFAULT_NOTICE_ICON_RES_ID;
        mCheckResultCallback = this;
        mLibraryResultCallaback = updateCheckerResult;
        mCustomImplementation = true;
    }

    /**
     * Set the store where download the app page from. Default is Google Play.
     *
     * @param store Store to set
     * @see com.rampo.updatechecker.store.Store
     * @see com.rampo.updatechecker.store.Store#GOOGLE_PLAY
     */
    public static void setStore(Store store) {
        mStore = store;
    }

    /**
     * Set the checks successful necessary to show the Notice. Default is 5.
     *
     * @param checksRequired checks required to set
     * @see com.rampo.updatechecker.notice.Notice
     */
    public static void setSuccessfulChecksRequired(int checksRequired) {
        mSuccessfulChecksRequired = checksRequired;
    }

    /**
     * Set the type of notice used to alert the user if a new update has been found. Default is Dialog.
     *
     * @param notice to set.
     * @see com.rampo.updatechecker.notice.Notice
     * @see com.rampo.updatechecker.notice.Notice#DIALOG
     */
    public static void setNotice(Notice notice) {
        mNotice = notice;
        if (mCustomImplementation) {
            throw new IllegalStateException("You can't set Notice when you choose a custom implementation.\nThe Notice is controlled manually by you with the callbacks.\nTo call setNotice() use the UpdateChecker constructor with one argument.");
        }
    }

    /**
     * Set the Notifcation or Dialog icon. If you don't call this, the Notifcation will have the default Play Store Notification Icon as icon and the Dialog will have no icon.
     *
     * @param noticeIconResId Res Id of the icon to set.
     * @see com.rampo.updatechecker.notice.Notification
     * @see com.rampo.updatechecker.notice.Dialog
     */
    public static void setNoticeIcon(int noticeIconResId) {
        mNoticeIconResId = noticeIconResId;
        if (mCustomImplementation) {
            throw new IllegalStateException("You can't set the notice Icon when you choose a custom implementation.\nThe Notice is controlled manually by you with the callbacks.\nTo call setNotice() use the UpdateChecker constructor with one argument.");
        }
    }

    /**
     * Start the process
     */
    public static void start() {
        ASyncCheck asynctask = new ASyncCheck(mStore, mCheckResultCallback, mActivity);
        asynctask.execute();
    }

    /**
     * If the library found a version available on the Store, and it's different from the installed one, notify it to the user.
     *
     * @param versionDownloadable String to compare to the version installed of the app.
     */
    @Override
    public void versionDownloadableFound(String versionDownloadable) {
        if (Comparator.isVersionDownloadableNewer(mActivity, versionDownloadable)) {
            if (hasToShowNotice(versionDownloadable) && !hasUserTappedToNotShowNoticeAgain(versionDownloadable)) {
                mLibraryResultCallaback.foundUpdateAndShowIt(versionDownloadable);
            } else {
                mLibraryResultCallaback.foundUpdateAndDontShowIt(versionDownloadable);
            }
        } else { // No new update available
            mLibraryResultCallaback.returnUpToDate(versionDownloadable);
        }

    }

    /**
     * Can't get the versionName from Play Store.
     * See #1 error.
     *
     * @see Issue #1
     */
    @Override
    public void multipleApksPublished() {
        mLibraryResultCallaback.returnMultipleApksPublished();
    }

    /**
     * Can't download the store page.
     */
    @Override
    public void networkError() {
        mLibraryResultCallaback.returnNetworkError();
    }

    /**
     * Can't find the store page for this app.
     */
    @Override
    public void appUnpublished() {
        mLibraryResultCallaback.returnAppUnpublished();
    }

    /**
     * The check returns null for new version downloadble
     */
    @Override
    public void storeError() {
        mLibraryResultCallaback.returnStoreError();
    }

    /**
     * versionDownloadable isn't equal to manifest versionName -> New update available.
     * Show the Notice because it's the first time or the number of the checks made is a multiple of the argument of setSuccessfulChecksRequired(int) method. (If you don't call setSuccessfulChecksRequired(int) the default is 5).
     *
     * @param versionDownloadable version downloadable from the Store.
     * @see com.rampo.updatechecker.UpdateChecker#setSuccessfulChecksRequired(int)
     */
    @Override
    public void foundUpdateAndShowIt(String versionDownloadable) {
        if (mNotice == Notice.NOTIFICATION) {
            showNotification();
        } else if (mNotice == Notice.DIALOG) {
            showDialog(versionDownloadable);
        }
    }

    /**
     * versionDownloadable isn't equal to manifest versionName -> New update available.
     * Show the Notice because it's the first time or the number of the checks made is a multiple of the argument of setSuccessfulChecksRequired(int) method. (If you don't call setSuccessfulChecksRequired(int) the default is 5).
     *
     * @param versionDownloadable version downloadable from the Store.
     * @see com.rampo.updatechecker.UpdateChecker#setSuccessfulChecksRequired(int)
     */
    @Override
    public void foundUpdateAndDontShowIt(String versionDownloadable) {

    }

    /**
     * versionDownloadable is equal to manifest versionName -> No new update available.
     * Don't show the Notice
     *
     * @param versionDonwloadable version downloadable from the Store.
     */
    @Override
    public void returnUpToDate(String versionDonwloadable) {

    }

    @Override
    public void returnMultipleApksPublished() {

    }

    @Override
    public void returnNetworkError() {

    }

    @Override
    public void returnAppUnpublished() {

    }

    @Override
    public void returnStoreError() {

    }

    /**
     * Get if the user has tapped on "No, thanks" button on dialog for this downloable version.
     *
     * @param versionDownloadable version downloadable from the Store.
     * @see com.rampo.updatechecker.notice.Dialog#userHasTappedToNotShowNoticeAgain(android.content.Context, String)
     */
    private boolean hasUserTappedToNotShowNoticeAgain(String versionDownloadable) {
        SharedPreferences prefs = mActivity.getSharedPreferences(PREFS_FILENAME, 0);
        String prefKey = DONT_SHOW_AGAIN_PREF_KEY + versionDownloadable;
        return prefs.getBoolean(prefKey, false);
    }

    /**
     * Show the Notice only if it's the first time or the number of the checks made is a multiple of the argument of setSuccessfulChecksRequired(int) method. (If you don't call setSuccessfulChecksRequired(int) the default is 5).
     */
    private boolean hasToShowNotice(String versionDownloadable) {
        SharedPreferences prefs = mActivity.getSharedPreferences(PREFS_FILENAME, 0);
        String prefKey = SUCCESSFUL_CHEKS_PREF_KEY + versionDownloadable;
        int mChecksMade = prefs.getInt(prefKey, 0);
        if (mChecksMade % mSuccessfulChecksRequired == 0 || mChecksMade == 0) {
            saveNumberOfChecksForUpdatedVersion(versionDownloadable, mChecksMade);
            return true;
        } else {
            saveNumberOfChecksForUpdatedVersion(versionDownloadable, mChecksMade);
            return false;
        }
    }

    /**
     * Update number of checks for this version downloadable from the Store.
     */
    private void saveNumberOfChecksForUpdatedVersion(String versionDownloadable, int mChecksMade) {
        mChecksMade++;
        SharedPreferences prefs = mActivity.getSharedPreferences(PREFS_FILENAME, 0);
        SharedPreferences.Editor editor = prefs.edit();
        editor.putInt(SUCCESSFUL_CHEKS_PREF_KEY + versionDownloadable, mChecksMade);
        editor.commit();

    }

    /**
     * Show Dialog
     */
    public void showDialog(String versionDownloadable) {
        Dialog.show(mActivity, mStore, versionDownloadable, mNoticeIconResId);
    }

    /**
     * Show Notification
     */
    public static void showNotification() {
        Notification.show(mActivity, mStore, mNoticeIconResId);
    }

    /**
     * Show a Dialog if an update is available for download. Callable in a FragmentActivity.
     * Number of checks after the dialog will be shown: 5 (default)
     *
     * @param fragmentActivity required.
     */
    @Deprecated
    public static void checkForDialog(FragmentActivity fragmentActivity) {
    }

    /**
     * Show a Dialog if an update is available for download. Callable in a FragmentActivity.
     * Specify the number of checks after the dialog will be shown.
     *
     * @param fragmentActivity         Required.
     * @param successfulChecksRequired The number of checks after the dialog will be shown.
     */
    @Deprecated
    public static void checkForDialog(FragmentActivity fragmentActivity, int successfulChecksRequired) {
    }

    /**
     * Show a Notification if an update is available for download. Callable in a FragmentActivity
     * Number of checks after the dialog will be shown: 5 (default)
     *
     * @param fragmentActivity Required.
     */
    @Deprecated
    public static void checkForNotification(FragmentActivity fragmentActivity) {
    }

    /**
     * Show a Notification if an update is available for download. Callable in a FragmentActivity
     * Specify the number of checks after the notification will be shown.
     *
     * @param fragmentActivity         Required.
     * @param successfulChecksRequired The number of checks after the notification will be shown.
     */
    @Deprecated
    public static void checkForNotification(FragmentActivity fragmentActivity, int successfulChecksRequired) {
    }

    /**
     * Show a Notification if an update is available for download. Callable in a FragmentActivity
     * Specify the number of checks after the notification will be shown.
     *
     * @param fragmentActivity      Required.
     * @param notificationIconResId R.drawable.* resource to set to Notification icon.
     */
    @Deprecated
    public static void checkForNotification(int notificationIconResId, FragmentActivity fragmentActivity) {
    }

    /**
     * Show a Notification if an update is available for download. Set the notificationIcon Resource Id. Callable in a FragmentActivity
     * Specify the number of checks after the notification will be shown.
     *
     * @param fragmentActivity         Required
     * @param successfulChecksRequired The number of checks after the notification will be shown.
     * @param notificationIconResId    R.drawable.* resource to set to Notification icon.
     */
    @Deprecated
    public static void checkForNotification(int notificationIconResId, FragmentActivity fragmentActivity, int successfulChecksRequired) {
    }

    /**
     * Show a Dialog if an update is available for download. Callable in a FragmentActivity.
     *
     * @param fragmentActivity Required.
     * @deprecated use {@link #checkForDialog(FragmentActivity)} instead.
     */
    @Deprecated
    public static void CheckForDialog(FragmentActivity fragmentActivity) {
        checkForDialog(fragmentActivity);
    }

    /**
     * Show a Notification if an update is available for download. Callable in a FragmentActivity
     *
     * @param fragmentActivity Required.
     * @deprecated use {@link #checkForNotification(FragmentActivity)} instead.
     */
    @Deprecated
    public static void CheckForNotification(FragmentActivity fragmentActivity) {
        checkForNotification(fragmentActivity);
    }

    /**
     * Show a Notification if an update is available for download. Set the notificationIcon Resource Id. Callable in a FragmentActivity
     *
     * @param fragmentActivity      Required
     * @param notificationIconResId R.drawable.* resource to set to Notification Icon.
     * @deprecated use {@link #checkForNotification(FragmentActivity, int)} instead.
     */
    @Deprecated
    public static void CheckForNotification(FragmentActivity fragmentActivity, int notificationIconResId) {
        checkForNotification(fragmentActivity, notificationIconResId);
    }
}