@Override
    public List<Intent> compile(MultiPointToSinglePointIntent intent, List<Intent> installable) {
        Map<DeviceId, Link> links = new HashMap<>();
        ConnectPoint egressPoint = intent.egressPoint();

        final boolean allowMissingPaths = intentAllowsPartialFailure(intent);
        boolean hasPaths = false;
        boolean missingSomePaths = false;

        for (ConnectPoint ingressPoint : intent.ingressPoints()) {
            if (ingressPoint.deviceId().equals(egressPoint.deviceId())) {
                if (deviceService.isAvailable(ingressPoint.deviceId())) {
                    hasPaths = true;
                } else {
                    missingSomePaths = true;
                }
                continue;
            }

            Path path = getPath(intent, ingressPoint.deviceId(), egressPoint.deviceId());

            if (path != null) {
                hasPaths = true;

                for (Link link : path.links()) {
                    if (links.containsKey(link.dst().deviceId())) {
                        // We've already reached the existing tree with the first
                        // part of this path. Add the merging point with different
                        // incoming port, but don't add the remainder of the path
                        // in case it differs from the path we already have.
                        links.put(link.src().deviceId(), link);
                        break;
                    }
                    links.put(link.src().deviceId(), link);
                }
            } else {
                missingSomePaths = true;
            }
        }

        // Allocate bandwidth on existing paths if a bandwidth constraint is set
        List<ConnectPoint> ingressCPs =
                intent.filteredIngressPoints().stream()
                                              .map(fcp -> fcp.connectPoint())
                                              .collect(Collectors.toList());
        ConnectPoint egressCP = intent.filteredEgressPoint().connectPoint();

        List<ConnectPoint> pathCPs =
                links.values().stream()
                              .flatMap(l -> Stream.of(l.src(), l.dst()))
                              .collect(Collectors.toList());

        pathCPs.addAll(ingressCPs);
        pathCPs.add(egressCP);

        allocateBandwidth(intent, pathCPs);

        if (!hasPaths) {
            throw new IntentException("Cannot find any path between ingress and egress points.");
        } else if (!allowMissingPaths && missingSomePaths) {
            throw new IntentException("Missing some paths between ingress and egress points.");
        }

        Intent result = LinkCollectionIntent.builder()
                .appId(intent.appId())
                .key(intent.key())
                .treatment(intent.treatment())
                .selector(intent.selector())
                .links(Sets.newHashSet(links.values()))
                .filteredIngressPoints(intent.filteredIngressPoints())
                .filteredEgressPoints(ImmutableSet.of(intent.filteredEgressPoint()))
                .priority(intent.priority())
                .constraints(intent.constraints())
                .resourceGroup(intent.resourceGroup())
                .build();

        return Collections.singletonList(result);
    }
@Test
    public void testTwoIngressCompilation() {
        Set<FilteredConnectPoint> ingress =
                Sets.newHashSet(new FilteredConnectPoint(new ConnectPoint(DID_1, PORT_1)),
                                new FilteredConnectPoint(new ConnectPoint(DID_2, PORT_1)));
        FilteredConnectPoint egress =
                new FilteredConnectPoint(new ConnectPoint(DID_4, PORT_1));

        MultiPointToSinglePointIntent intent = makeIntent(ingress, egress);
        assertThat(intent, is(notNullValue()));

        final String[] hops = {S3};
        MultiPointToSinglePointIntentCompiler compiler = makeCompiler(hops);
        assertThat(compiler, is(notNullValue()));

        List<Intent> result = compiler.compile(intent, null);
        assertThat(result, is(notNullValue()));
        assertThat(result, hasSize(1));
        Intent resultIntent = result.get(0);
        assertThat(resultIntent instanceof LinkCollectionIntent, is(true));

        if (resultIntent instanceof LinkCollectionIntent) {
            LinkCollectionIntent linkIntent = (LinkCollectionIntent) resultIntent;
            assertThat(linkIntent.links(), hasSize(3));
            assertThat(linkIntent.links(), linksHasPath(S1, S3));
            assertThat(linkIntent.links(), linksHasPath(S2, S3));
            assertThat(linkIntent.links(), linksHasPath(S3, S4));
        }
        assertThat("key is inherited", resultIntent.key(), is(intent.key()));
    }