docs: protected static <S extends AddressSegment> Iterator<S[]> iterator(
  			int divCount,
  			AddressSegmentCreator<S> segmentCreator,
  			Supplier<S[]> segSupplier,//provides the original segments in an array for a single valued iterator
  			IntFunction<Iterator<S>> segIteratorProducer,
  			Predicate<S[]> excludeFunc,
  			int networkSegmentIndex,
  			int hostSegmentIndex,
  			IntFunction<Iterator<S>> prefixedSegIteratorProducer) {
  		if(segSupplier != null) {
  			return new Iterator<S[]>() {
  				S result[] = segSupplier.get(); {
  					if(excludeFunc != null && excludeFunc.test(result)) {
  						result = null;
  					}
  				}
  				
  				@Override
  				public boolean hasNext() {
  					return result != null;
  				}
  
  			    @Override
  				public S[] next() {
  			    	if(result == null) {
  			    		throw new NoSuchElementException();
  			    	}
  			    	S res[] = result;
  			    	result = null;
  			    	return res;
  			    }
  
  			    @Override
  				public void remove() {
  			    	throw new UnsupportedOperationException();
  			    }
  			};
  		}
  		
  		return new Iterator<S[]>() {
  			private boolean done;
  				
  			@SuppressWarnings("unchecked")
  			private final Iterator<S> variations[] = new Iterator[divCount];
  			
  			private S nextSet[] = segmentCreator.createSegmentArray(divCount);  {
  				updateVariations(0);
  				for(int i = networkSegmentIndex + 1; i < divCount; i++) {//for regular iterators (not prefix block), networkSegmentIndex is last segment (count - 1)
  					variations[i] = prefixedSegIteratorProducer.apply(i);
  					nextSet[i] = variations[i].next();
  				}
  				if(excludeFunc != null && excludeFunc.test(nextSet)) {
  					increment();
  				}
  			}
  			
  			private void updateVariations(int start) {
  				int i = start;
  				for(; i < hostSegmentIndex; i++) {
  					variations[i] = segIteratorProducer.apply(i);
  					nextSet[i] = variations[i].next();
  				}
  				if(i == networkSegmentIndex) {
  					variations[i] = prefixedSegIteratorProducer.apply(i);
  					nextSet[i] = variations[i].next();
  				}
  			}
  			
  			@Override
  			public boolean hasNext() {
  				return !done;
  			}
  			
  		    @Override
  			public S[] next() {
  		    	if(done) {
  		    		throw new NoSuchElementException();
  		    	}
  		    	return increment();
  		    }
  		    
  		    private S[] increment() {
  		    	S previousSegs[] = null;
  		    	for(int j = networkSegmentIndex; j >= 0; j--) {//for regular iterators (not prefix block), networkSegmentIndex is last segment (count - 1)
  		    		while(variations[j].hasNext()) {
  		    			if(previousSegs == null) {
  		    				previousSegs = nextSet.clone();
  		    			}
  		    			nextSet[j] = variations[j].next();
  		    			updateVariations(j + 1);
  		    			if(excludeFunc != null && excludeFunc.test(nextSet)) {
  		    				j = networkSegmentIndex;
  						} else {
  							return previousSegs;
  						}
  		    		}
  		    	}
  		    	done = true;
  		    	return previousSegs == null ? nextSet : previousSegs;
  		    }
  
  		    @Override
  			public void remove() {
  		    	throw new UnsupportedOperationException();
  		    }
  		};
  	}