@NonNull
 public Set<LayoutNode> canGrowLeft() {
   Set<LayoutNode> nodes;
   if (mToRight != null) {
     nodes = mToRight.canGrowLeft();
   } else {
     nodes = new LinkedHashSet<LayoutNode>();
   }
   if (!fixedWidth()) {
     nodes.add(this);
   }
   return nodes;
 }
  @Override
  public void visitElement(@NonNull XmlContext context, @NonNull Element element) {
    // Traverse all child elements
    NodeList childNodes = element.getChildNodes();
    int count = childNodes.getLength();
    Map<String, LayoutNode> nodes = Maps.newHashMap();
    for (int i = 0; i < count; i++) {
      Node node = childNodes.item(i);
      if (node.getNodeType() == Node.ELEMENT_NODE) {
        LayoutNode ln = new LayoutNode((Element) node, i);
        nodes.put(ln.getNodeId(), ln);
      }
    }

    // Node map is populated, recalculate nodes sizes
    for (LayoutNode ln : nodes.values()) {
      ln.processNode(nodes);
    }
    for (LayoutNode right : nodes.values()) {
      if (!right.mLastLeft || right.skip()) {
        continue;
      }
      Set<LayoutNode> canGrowLeft = right.canGrowLeft();
      for (LayoutNode left : nodes.values()) {
        if (left == right || !left.mLastRight || left.skip() || !left.sameBucket(right)) {
          continue;
        }
        Set<LayoutNode> canGrowRight = left.canGrowRight();
        if (canGrowLeft.size() > 0 || canGrowRight.size() > 0) {
          canGrowRight.addAll(canGrowLeft);
          LayoutNode nodeToBlame = right;
          LayoutNode otherNode = left;
          if (!canGrowRight.contains(right) && canGrowRight.contains(left)) {
            nodeToBlame = left;
            otherNode = right;
          }
          context.report(
              ISSUE,
              nodeToBlame.getNode(),
              context.getLocation(nodeToBlame.getNode()),
              String.format(
                  "`%1$s` can overlap `%2$s` if %3$s %4$s due to localized text expansion",
                  nodeToBlame.getNodeId(),
                  otherNode.getNodeId(),
                  Joiner.on(", ").join(canGrowRight),
                  canGrowRight.size() > 1 ? "grow" : "grows"));
        }
      }
    }
  }