public static Collection<AbstractAttribute> findAllAttributes(
            final boolean parallel, final AbstractHtml... fromTags)
            throws NullValueException {
    """
	Finds all attributes from the given tags
	
	@param parallel
	true to internally use parallel stream. If true it
	will split the finding task to different batches and
	will execute the batches in different threads in
	parallel consuming all CPUs. It will perform faster
	in finding from extremely large number of tags but at
	the same time it will less efficient in finding from
	small number of tags.
	@param fromTags
	the tags to find the attributes from.
	@return the all attributes from the given tags including the nested tags.
	@throws NullValueException
	if {@code fromTags} is null
	@since 3.0.0
	@author WFF
    """

        if (fromTags == null) {
            throw new NullValueException("fromTags cannot be null");
        }

        final Collection<Lock> locks = getReadLocks(fromTags);
        for (final Lock lock : locks) {
            lock.lock();
        }
        try {
            return getAllNestedChildrenIncludingParent(parallel, fromTags)
                    .filter(tag -> tag.getAttributes() != null).map(tag -> {
                        return tag.getAttributes();
                    }).flatMap(attributes -> attributes.stream())
                    .collect(Collectors.toSet());
        } finally {
            for (final Lock lock : locks) {
                lock.unlock();
            }
        }
    }
public static Collection<AbstractAttribute> findAllAttributes(
            final boolean parallel, final AbstractHtml... fromTags)
            throws NullValueException {

        if (fromTags == null) {
            throw new NullValueException("fromTags cannot be null");
        }

        final Collection<Lock> locks = getReadLocks(fromTags);
        for (final Lock lock : locks) {
            lock.lock();
        }
        try {
            return getAllNestedChildrenIncludingParent(parallel, fromTags)
                    .filter(tag -> tag.getAttributes() != null).map(tag -> {
                        return tag.getAttributes();
                    }).flatMap(attributes -> attributes.stream())
                    .collect(Collectors.toSet());
        } finally {
            for (final Lock lock : locks) {
                lock.unlock();
            }
        }
    }
public static Collection < AbstractAttribute > findAllAttributes ( final boolean parallel , final AbstractHtml ... fromTags ) throws NullValueException { if ( fromTags == null ) { throw new NullValueException ( "fromTags cannot be null" ) ; } final Collection < Lock > locks = getReadLocks ( fromTags ) ; for ( final Lock lock : locks ) { lock . lock ( ) ; } try { return getAllNestedChildrenIncludingParent ( parallel , fromTags ) . filter ( tag -> tag . getAttributes ( ) != null ) . map ( tag -> { return tag . getAttributes ( ) ; } ) . flatMap ( attributes -> attributes . stream ( ) ) . collect ( Collectors . toSet ( ) ) ; } finally { for ( final Lock lock : locks ) { lock . unlock ( ) ; } } }
Finds all attributes from the given tags

@param parallel
true to internally use parallel stream. If true it
will split the finding task to different batches and
will execute the batches in different threads in
parallel consuming all CPUs. It will perform faster
in finding from extremely large number of tags but at
the same time it will less efficient in finding from
small number of tags.
@param fromTags
the tags to find the attributes from.
@return the all attributes from the given tags including the nested tags.
@throws NullValueException
if {@code fromTags} is null
@since 3.0.0
@author WFF
Finds all attributes from the given tags