docs: ScopeNode addChild(ScopeNode child) {
      if (child == null) {
        throw new IllegalArgumentException("Child must be non null.");
      }
  
      //this variable is important. It takes a snapshot of the node
      final ScopeNode parentScope = child.getParentScope();
      if (parentScope == this) {
        return child;
      }
  
      if (parentScope != null) {
        throw new IllegalStateException(format("Scope %s already has a parent: %s which is not %s", child, parentScope, this));
      }
  
      //non-locking allows multiple threads to arrive here,
      //we take into account the first one only
      ScopeNode scope = childrenScopes.putIfAbsent(child.getName(), child);
      if (scope != null) {
        return scope;
      }
      //this could bug in multi-thread if a node is added to 2 parents...
      //there is no atomic operation to add them both and getting sure they are the only parent scopes.
      //we choose not to lock as this scenario doesn't seem meaningful
      child.parentScopes.add(this);
      child.parentScopes.addAll(parentScopes);
      return child;
    }