code: public void parse(UNode tenantNode) {
          assert tenantNode != null;
          m_name = tenantNode.getName();
          
          for (String childName : tenantNode.getMemberNames()) {
              UNode childNode = tenantNode.getMember(childName);
              switch (childNode.getName()) {
              case "options":
                  for (UNode optNode : childNode.getMemberList()) {
                      m_options.put(optNode.getName(), parseOption(optNode));
                  }
                  break;
              case "users":
                  for (UNode userNode : childNode.getMemberList()) {
                      UserDefinition userDef = new UserDefinition();
                      userDef.parse(userNode);
                      m_users.put(userDef.getID(), userDef);
                  }
                  break;
              case "properties":
                  for (UNode propNode : childNode.getMemberList()) {
                      Utils.require(propNode.isValue(), "'property' must be a value: " + propNode);
                      m_properties.put(propNode.getName(), propNode.getValue());
                  }
                  break;
              default:
                  Utils.require(false, "Unknown tenant property: " + childNode);
              }
          }            
      }
docs: Parse the tenant definition rooted at given UNode tree and update this object to
  match. The root node is the "tenant" object, so its name is the tenant name and its
  child nodes are tenant definitions such as "users" and "options". An exception is
  thrown if the definition contains an error.
  
  @param tenantNode    Root of a UNode tree that defines a tenant.