class NavigationContextImpl implements NavigationContext<T> {

    @Override
    public boolean equals(final Object o) {
        if (this == o) return true;
        if (!(o instanceof NavigationContextImpl)) return false;

        final NavigationContextImpl that = (NavigationContextImpl) o;

        if (shopId != that.shopId) return false;
        if (customerShopId != that.customerShopId) return false;
        if (includeSubCategories != that.includeSubCategories) return false;
        if (customerLanguage != null ? !customerLanguage.equals(that.customerLanguage) : that.customerLanguage != null)
            return false;
        if (categories != null) {
            if (that.categories == null || categories.size() != that.categories.size()) return false;
            for (int i = 0; i < categories.size(); i++) {
                if (!categories.get(i).equals(that.categories.get(i))) return false;
            }
        } else if (that.categories != null) return false;

        if (navigationParameters.size() != that.navigationParameters.size()) return false;
        for (final Map.Entry<String, List<String>> entry : navigationParameters.entrySet()) {
            final List<String> thatValue = (List<String>) that.navigationParameters.get(entry.getKey());
            if (entry.getValue() != null) {
                if (thatValue == null || entry.getValue().size() != thatValue.size()) return false;
                for (int i = 0; i < thatValue.size(); i++) {
                    if (!entry.getValue().get(i).equals(thatValue.get(i))) return false;
                }
            } else if (thatValue != null) return false;
        }

        return true;
    }

    public  NavigationContextImpl(final long shopId,
                                 final long customerShopId,
                                 final String customerLanguage,
                                 final List<Long> categories,
                                 final boolean includeSubCategories,
                                 final Map<String, List<String>> navigationParameters,
                                 final T productQuery,
                                 final T productSkuQuery);

}