class ControllerSearchService {

    public void search(final SearchResultsDTO results, final String search, final ProcessGroup group) {
        final NiFiUser user = NiFiUserUtils.getNiFiUser();

        if (group.isAuthorized(authorizer, RequestAction.READ, user)) {
            final ComponentSearchResultDTO groupMatch = search(search, group);
            if (groupMatch != null) {
                // get the parent group, not the current one
                groupMatch.setParentGroup(buildResultGroup(group.getParent(), user));
                groupMatch.setVersionedGroup(buildVersionedGroup(group.getParent(), user));
                results.getProcessGroupResults().add(groupMatch);
            }
        }

        for (final ProcessorNode procNode : group.getProcessors()) {
            if (procNode.isAuthorized(authorizer, RequestAction.READ, user)) {
                final ComponentSearchResultDTO match = search(search, procNode);
                if (match != null) {
                    match.setGroupId(group.getIdentifier());
                    match.setParentGroup(buildResultGroup(group, user));
                    match.setVersionedGroup(buildVersionedGroup(group, user));
                    results.getProcessorResults().add(match);
                }
            }
        }

        for (final Connection connection : group.getConnections()) {
            if (connection.isAuthorized(authorizer, RequestAction.READ, user)) {
                final ComponentSearchResultDTO match = search(search, connection);
                if (match != null) {
                    match.setGroupId(group.getIdentifier());
                    match.setParentGroup(buildResultGroup(group, user));
                    match.setVersionedGroup(buildVersionedGroup(group, user));
                    results.getConnectionResults().add(match);
                }
            }
        }

        for (final RemoteProcessGroup remoteGroup : group.getRemoteProcessGroups()) {
            if (remoteGroup.isAuthorized(authorizer, RequestAction.READ, user)) {
                final ComponentSearchResultDTO match = search(search, remoteGroup);
                if (match != null) {
                    match.setGroupId(group.getIdentifier());
                    match.setParentGroup(buildResultGroup(group, user));
                    match.setVersionedGroup(buildVersionedGroup(group, user));
                    results.getRemoteProcessGroupResults().add(match);
                }
            }
        }

        for (final Port port : group.getInputPorts()) {
            if (port.isAuthorized(authorizer, RequestAction.READ, user)) {
                final ComponentSearchResultDTO match = search(search, port);
                if (match != null) {
                    match.setGroupId(group.getIdentifier());
                    match.setParentGroup(buildResultGroup(group, user));
                    match.setVersionedGroup(buildVersionedGroup(group, user));
                    results.getInputPortResults().add(match);
                }
            }
        }

        for (final Port port : group.getOutputPorts()) {
            if (port.isAuthorized(authorizer, RequestAction.READ, user)) {
                final ComponentSearchResultDTO match = search(search, port);
                if (match != null) {
                    match.setGroupId(group.getIdentifier());
                    match.setParentGroup(buildResultGroup(group, user));
                    match.setVersionedGroup(buildVersionedGroup(group, user));
                    results.getOutputPortResults().add(match);
                }
            }
        }

        for (final Funnel funnel : group.getFunnels()) {
            if (funnel.isAuthorized(authorizer, RequestAction.READ, user)) {
                final ComponentSearchResultDTO match = search(search, funnel);
                if (match != null) {
                    match.setGroupId(group.getIdentifier());
                    match.setParentGroup(buildResultGroup(group, user));
                    match.setVersionedGroup(buildVersionedGroup(group, user));
                    results.getFunnelResults().add(match);
                }
            }
        }

        for (final ProcessGroup processGroup : group.getProcessGroups()) {
            search(results, search, processGroup);
        }
    }

}