public static Optional<HeaderSpace> intersect(HeaderSpace h1, HeaderSpace h2) {
checkArgument(isUnconstrained(h1.getSrcOrDstIps()));
checkArgument(isUnconstrained(h2.getSrcOrDstIps()));
checkArgument(isUnconstrained(h1.getSrcOrDstPorts()));
checkArgument(isUnconstrained(h2.getSrcOrDstPorts()));
checkArgument(isUnconstrained(h1.getSrcOrDstProtocols()));
checkArgument(isUnconstrained(h2.getSrcOrDstProtocols()));
try {
return Optional.of(
HeaderSpace.builder()
.setDscps(intersectSimpleSets(h1.getDscps(), h2.getDscps()))
.setDstIps(intersection(h1.getDstIps(), h2.getDstIps()))
.setDstPorts(intersectSubRangeSets(h1.getDstPorts(), h2.getDstPorts()))
.setDstProtocols(intersectSimpleSets(h1.getDstProtocols(), h2.getDstProtocols()))
.setIpProtocols(intersectSimpleSets(h1.getIpProtocols(), h2.getIpProtocols()))
.setIcmpCodes(intersectSubRangeSets(h1.getIcmpCodes(), h2.getIcmpCodes()))
.setIcmpTypes(intersectSubRangeSets(h1.getIcmpTypes(), h2.getIcmpTypes()))
.setNotDstIps(AclIpSpace.union(h1.getNotDstIps(), h2.getNotDstIps()))
.setNotDstPorts(Sets.union(h1.getNotDstPorts(), h2.getNotDstPorts()))
.setNotSrcIps(AclIpSpace.union(h1.getNotSrcIps(), h2.getNotSrcIps()))
.setNotSrcPorts(Sets.union(h1.getNotSrcPorts(), h2.getNotSrcPorts()))
.setSrcIps(AclIpSpace.intersection(h1.getSrcIps(), h2.getSrcIps()))
.setSrcOrDstPorts(intersectSubRangeSets(h1.getSrcOrDstPorts(), h2.getSrcOrDstPorts()))
.setSrcPorts(intersectSubRangeSets(h1.getSrcPorts(), h2.getSrcPorts()))
.setTcpFlags(intersectTcpFlagMatchConditions(h1.getTcpFlags(), h2.getTcpFlags()))
.build());
} catch (NoIntersection e) {
return Optional.empty();
}
}