private void validateIntersections(
      final PreparedUpdate update,
      final UpdateContext updateContext,
      final IpInterval ipInterval,
      final IpTree ipTree) {
    final List<IpEntry> parent = ipTree.findFirstLessSpecific(ipInterval);
    Validate.notEmpty(parent, "Should always have a parent");

    Interval firstIntersecting = null;
    final List<IpEntry> childEntries =
        ipTree.findFirstMoreSpecific((IpInterval) parent.get(0).getKey());
    for (final IpEntry childEntry : childEntries) {
      final Interval child = childEntry.getKey();

      if (child.intersects(ipInterval)
          && !(child.contains(ipInterval) || ipInterval.contains(child))) {
        if (firstIntersecting == null
            || firstIntersecting
                    .singletonIntervalAtLowerBound()
                    .compareUpperBound(child.singletonIntervalAtLowerBound())
                > 0) {
          firstIntersecting = child;
        }
      }
    }

    if (firstIntersecting != null) {
      updateContext.addMessage(update, UpdateMessages.intersectingRange(firstIntersecting));
    }
  }
 @Override
 public void validate(final PreparedUpdate update, final UpdateContext updateContext) {
   final IpInterval ipInterval = IpInterval.parse(update.getReferenceObject().getKey());
   if (ipInterval instanceof Ipv4Resource) {
     validateIntersections(update, updateContext, ipInterval, ipv4Tree);
   } else {
     validateIntersections(update, updateContext, ipInterval, ipv6Tree);
   }
 }
  private Response doSyncUpdate(final Request request) {
    loggerContext.init(getRequestId(request.getRemoteAddress()));

    try {
      if (!sourceMatchesContext(request.getSource())) {
        return Response.status(Response.Status.BAD_REQUEST)
            .entity("Invalid source specified: " + request.getSource())
            .build();
      }

      boolean notificationsEnabled = true;
      if (request.isParam(Command.REDIRECT)) {
        if (!ipRanges.isTrusted(IpInterval.parse(request.getRemoteAddress()))) {
          return Response.status(Response.Status.FORBIDDEN)
              .entity("Not allowed to disable notifications: " + request.getRemoteAddress())
              .build();
        }

        notificationsEnabled = false;
      }

      if (!request.hasParam(Command.DATA) && request.isParam(Command.NEW)) {
        return Response.status(Response.Status.BAD_REQUEST)
            .entity("DATA parameter is missing")
            .build();
      }

      if (!request.hasParam(Command.DATA) && !request.isParam(Command.HELP)) {
        return Response.status(Response.Status.BAD_REQUEST).entity("Invalid request").build();
      }

      loggerContext.log("msg-in.txt", new SyncUpdateLogCallback(request.toString()));

      final UpdateContext updateContext = new UpdateContext(loggerContext);

      final String content = request.hasParam("DATA") ? request.getParam("DATA") : "";

      final UpdateRequest updateRequest =
          new UpdateRequest(
              new SyncUpdate(dateTimeProvider, request.getRemoteAddress()),
              getKeyword(request),
              content,
              updatesParser.parse(
                  updateContext, Lists.newArrayList(new ContentWithCredentials(content))),
              notificationsEnabled);

      final UpdateResponse updateResponse =
          updateRequestHandler.handle(updateRequest, updateContext);
      loggerContext.log("msg-out.txt", new SyncUpdateLogCallback(updateResponse.getResponse()));
      return getResponse(updateResponse);

    } finally {
      loggerContext.remove();
    }
  }
  @Override
  public List<RpslObject> authenticate(
      final PreparedUpdate update, final UpdateContext updateContext) {
    final RpslObject updatedObject = update.getUpdatedObject();
    final RpslAttribute typeAttribute = updatedObject.getTypeAttribute();
    final IpInterval addressPrefix = IpInterval.parse(typeAttribute.getCleanValue());

    final List<RpslObject> ipObjects = getIpObjects(addressPrefix);
    if (ipObjects.isEmpty()) {
      throw new AuthenticationFailedException(
          UpdateMessages.authenticationFailed(
              updatedObject, typeAttribute.getType(), Collections.<RpslObject>emptyList()),
          Collections.<RpslObject>emptyList());
    }

    final Set<RpslObject> allCandidates = Sets.newLinkedHashSet();
    final List<Message> authenticationMessages = Lists.newArrayList();

    for (final RpslObject ipObject : ipObjects) {
      if (ipObject.containsAttribute(AttributeType.MNT_ROUTES)) {
        final List<RpslObject> candidates =
            getCandidatesForMntRoutesAuthentication(ipObject, update);
        allCandidates.addAll(candidates);

        final List<RpslObject> authenticated =
            authenticationModule.authenticate(update, updateContext, candidates);
        if (authenticated.isEmpty()) {
          authenticationMessages.add(
              UpdateMessages.authenticationFailed(ipObject, AttributeType.MNT_ROUTES, candidates));
        } else {
          return authenticated;
        }
      }
    }

    if (!authenticationMessages.isEmpty()) {
      throw new AuthenticationFailedException(authenticationMessages, allCandidates);
    }

    for (final RpslObject ipObject : ipObjects) {
      final IpInterval ipInterval = IpInterval.parse(ipObject.getTypeAttribute().getCleanValue());
      if (!addressPrefix.equals(ipInterval)
          && ipObject.containsAttribute(AttributeType.MNT_LOWER)) {
        final List<RpslObject> candidates =
            objectDao.getByKeys(
                ObjectType.MNTNER, ipObject.getValuesForAttribute(AttributeType.MNT_LOWER));
        allCandidates.addAll(candidates);

        final List<RpslObject> authenticated =
            authenticationModule.authenticate(update, updateContext, candidates);
        if (authenticated.isEmpty()) {
          authenticationMessages.add(
              UpdateMessages.authenticationFailed(ipObject, AttributeType.MNT_LOWER, candidates));
        } else {
          return authenticated;
        }
      }
    }

    if (!authenticationMessages.isEmpty()) {
      throw new AuthenticationFailedException(authenticationMessages, allCandidates);
    }

    for (final RpslObject ipObject : ipObjects) {
      if (ipObject.containsAttribute(AttributeType.MNT_BY)) {
        final List<RpslObject> candidates =
            objectDao.getByKeys(
                ObjectType.MNTNER, ipObject.getValuesForAttribute(AttributeType.MNT_BY));
        allCandidates.addAll(candidates);

        final List<RpslObject> authenticated =
            authenticationModule.authenticate(update, updateContext, candidates);
        if (authenticated.isEmpty()) {
          authenticationMessages.add(
              UpdateMessages.authenticationFailed(ipObject, AttributeType.MNT_BY, candidates));
        } else {
          return authenticated;
        }
      }
    }

    if (!authenticationMessages.isEmpty()) {
      throw new AuthenticationFailedException(authenticationMessages, allCandidates);
    }

    throw new AuthenticationFailedException(
        UpdateMessages.authenticationFailed(
            updatedObject, typeAttribute.getType(), Collections.<RpslObject>emptyList()),
        allCandidates);
  }