public PagingLoadResult<Example> getSPARQLQueryResultWithProperties(
      String query, List<String> properties, PagingLoadConfig config) throws AutoSPARQLException {
    List<Example> queryResult = new ArrayList<Example>();
    //		properties.remove("label");
    int limit = config.getLimit();
    int offset = config.getOffset();
    int totalLength = 10;

    if (currentQueryResultSize == -1) {
      try {
        ResultSetRewindable rs =
            SparqlQuery.convertJSONtoResultSet(
                selectCache.executeSelectQuery(endpoint, getCountQuery(query)));
        currentQueryResultSize = rs.next().getLiteral(rs.getResultVars().get(0)).getInt();
      } catch (Exception e) {
        e.printStackTrace();
        currentQueryResultSize = 10;
      }
    }
    totalLength = currentQueryResultSize;

    List<String> propertiesToDo = new ArrayList<String>(properties);

    for (Map<String, Object> prop2Value : propertiesCache.values()) {
      propertiesToDo.removeAll(prop2Value.keySet());
    }

    if (propertiesToDo.size() > 0) {
      String queryTriples = query.substring(18, query.length() - 1);
      StringBuilder newQuery = new StringBuilder();
      Map<String, String> var2URIMap = new HashMap<String, String>(propertiesToDo.size());

      if (propertiesToDo.size() == 1 && propertiesToDo.get(0).equals(RDFS.label.getURI())) {
        newQuery.append("SELECT DISTINCT ?x0 ?label ?imageURL{");
        newQuery.append(queryTriples);
        newQuery.append("?x0 <").append(RDFS.label).append("> ?label.\n");
        newQuery
            .append("OPTIONAL{?x0 <")
            .append("http://dbpedia.org/ontology/thumbnail")
            .append("> ?imageURL.}\n");
        newQuery.append("FILTER(LANGMATCHES(LANG(?label),'en'))");
        newQuery.append("}");
      } else {
        for (String property : propertiesToDo) {
          var2URIMap.put(
              property2LabelMap.get(property).replace(" ", "_").replace("(", "").replace(")", ""),
              property);
        }

        newQuery.append("SELECT DISTINCT ?x0 ?label ?imageURL ");
        for (String var : var2URIMap.keySet()) {
          newQuery.append("?").append(var).append(" ");
          newQuery.append("?").append(var).append("_label ");
        }
        newQuery.append("{");
        newQuery.append(queryTriples);
        newQuery.append("?x0 <").append(RDFS.label).append("> ?label.\n");
        newQuery
            .append("OPTIONAL{?x0 <")
            .append("http://dbpedia.org/ontology/thumbnail")
            .append("> ?imageURL.}\n");
        for (Entry<String, String> entry : var2URIMap.entrySet()) {
          newQuery
              .append("OPTIONAL{?x0 <")
              .append(entry.getValue())
              .append("> ?")
              .append(entry.getKey())
              .append(".}\n");
        }
        for (Entry<String, String> entry : var2URIMap.entrySet()) {
          newQuery
              .append("OPTIONAL{?")
              .append(entry.getKey())
              .append(" <")
              .append(RDFS.label)
              .append("> ?")
              .append(entry.getKey())
              .append("_label.\n");
          newQuery.append("FILTER(LANGMATCHES(LANG(?" + entry.getKey() + "_label),'en'))}\n");
        }
        newQuery.append("FILTER(LANGMATCHES(LANG(?label),'en'))");
        newQuery.append("}");
      }

      logger.debug("Query with properties:\n" + newQuery.toString());
      try {
        ResultSetRewindable rs =
            SparqlQuery.convertJSONtoResultSet(
                selectCache.executeSelectQuery(endpoint, modifyQuery(newQuery + " LIMIT 1000")));

        String uri;
        String label = "";
        String imageURL = "";
        QuerySolution qs;
        RDFNode object;
        while (rs.hasNext()) {
          qs = rs.next();
          uri = qs.getResource("x0").getURI();
          label = qs.getLiteral("label").getLexicalForm();
          imageURL = qs.getResource("imageURL") != null ? qs.getResource("imageURL").getURI() : "";
          Map<String, Object> properties2Value = propertiesCache.get(uri);
          if (properties2Value == null) {
            properties2Value = new HashMap<String, Object>();
            properties2Value.put(RDFS.label.getURI(), label);
            properties2Value.put("http://dbpedia.org/ontology/thumbnail", imageURL);
            propertiesCache.put(uri, properties2Value);
          }

          Object value;
          String property;
          for (Entry<String, String> entry : var2URIMap.entrySet()) {
            value = "";
            property = entry.getValue();

            object = qs.get(entry.getKey() + "_label");
            if (object == null) {
              object = qs.get(entry.getKey());
            }
            if (object != null) {
              if (object.isURIResource()) {
                value = object.asResource().getURI();
              } else if (object.isLiteral()) {
                Literal lit = object.asLiteral();
                //								if(lit.getDatatypeURI().equals(XSD.BOOLEAN)){
                //									property2DatatypeMap.put(property, Boolean.class);
                //									value = lit.getBoolean();
                //								} else if(lit.getDatatypeURI().equals(XSD.INT)){
                //									property2DatatypeMap.put(property, Integer.class);
                //									value = lit.getInt();
                //								} else if(lit.getDatatypeURI().equals(XSD.DOUBLE)){
                //									property2DatatypeMap.put(property, Double.class);
                //									value = lit.getDouble();
                //								} else if(lit.getDatatypeURI().equals(XSD.FLOAT)){
                //									property2DatatypeMap.put(property, Float.class);
                //									value = lit.getFloat();
                //								} else {
                //									property2DatatypeMap.put(property, String.class);
                //									value = object.asLiteral().getLexicalForm();
                //								}
                value = object.asLiteral().getLexicalForm();
              }
            }
            Object oldValue = properties2Value.get(property);
            if (oldValue != null && value != null) {
              value = oldValue + ", " + value;
            }
            properties2Value.put(property, value);
          }
        }
      } catch (Exception e) {
        logger.error("Error while getting result for query \n" + newQuery, e);
      }
    }

    Example example;
    int cnt = 0;
    for (Entry<String, Map<String, Object>> uri2PropertyValues : propertiesCache.entrySet()) {
      //			if(cnt++ == limit+offset){
      //				break;
      //			}
      //			if(cnt > offset){
      example = new Example();
      example.setAllowNestedValues(false);
      example.set("uri", uri2PropertyValues.getKey());
      Object value;
      String property;
      for (Entry<String, Object> property2Value : uri2PropertyValues.getValue().entrySet()) {
        property = property2Value.getKey();
        value = property2Value.getValue();
        //					if(value == null){
        //						Class cls = property2DatatypeMap.get(property);
        //						if(cls == String.class){
        //							value = "";
        //						} else if(cls == Integer.class){
        //							value = Integer.valueOf(-1);
        //						} else if(cls == Double.class){
        //							value = Double.valueOf(-1);
        //						} else if(cls == Float.class){
        //							value = Float.valueOf(-1);
        //						} else if(cls == Boolean.class){
        //							value = Boolean.FALSE;
        //						}
        //					}
        example.set(property, value);
      }
      queryResult.add(example);
      //			}

    }
    if (config.getSortInfo().getSortField() != null) {
      final String sortField = config.getSortInfo().getSortField();
      Collections.sort(
          queryResult,
          config
              .getSortInfo()
              .getSortDir()
              .comparator(
                  new Comparator<Example>() {

                    @Override
                    public int compare(Example o1, Example o2) {
                      return ((String) o1.get(sortField)).compareTo((String) o2.get(sortField));
                    }
                  }));
    }
    int start = config.getOffset();
    int end = queryResult.size();
    if (limit > 0) {
      end = Math.min(start + limit, end);
    }
    //		queryResult = queryResult.subList(start, end);
    ArrayList<Example> tmp = new ArrayList<Example>();
    for (int i = start; i < end; i++) {
      tmp.add(queryResult.get(i));
    }

    PagingLoadResult<Example> result = new BasePagingLoadResult<Example>(tmp);
    result.setOffset(offset);
    result.setTotalLength(totalLength);

    return result;
  }
  public PagingLoadResult<BeanObject> getPagingList(
      String modelName, Criteria criteria, List<String> wantedFields, PagingLoadConfig pgc) {
    List<BeanObject> list = new ArrayList<BeanObject>();

    Manager manager = getManager(modelName);
    String methodName = config.getListMethod(modelName);
    try {
      Method method =
          manager
              .getClass()
              .getMethod(methodName, new Class[] {int.class, int.class, Criteria.class});
      if (method == null) {
        throw new RuntimeException("Method with paging not found: " + methodName);
      }

      List ret = (List) method.invoke(manager, pgc.getOffset(), pgc.getLimit(), criteria);
      for (Iterator it = ret.iterator(); it.hasNext(); ) {
        ModelObject model = (ModelObject) it.next();
        try {
          Map<String, Object> props = getProperties(model, wantedFields);
          list.add(new BeanObject(model.getClass().getSimpleName(), props));
        } catch (IllegalAccessException e) {
          e.printStackTrace();
        } catch (InvocationTargetException e) {
          e.printStackTrace();
        } catch (NoSuchMethodException e) {
          e.printStackTrace();
        }
      }
    } catch (SecurityException e) {
      e.printStackTrace();
    } catch (IllegalArgumentException e) {
      e.printStackTrace();
    } catch (NoSuchMethodException e) {
      e.printStackTrace();
    } catch (IllegalAccessException e) {
      e.printStackTrace();
    } catch (InvocationTargetException e) {
      e.printStackTrace();
    }

    if (pgc.getSortInfo().getSortField() != null) {
      final String sortField = pgc.getSortInfo().getSortField();
      if (sortField != null) {
        Collections.sort(
            list,
            pgc.getSortInfo()
                .getSortDir()
                .comparator(
                    new Comparator() {
                      public int compare(Object o1, Object o2) {
                        Object s1 = ((BeanObject) o1).get(sortField);
                        Object s2 = ((BeanObject) o2).get(sortField);
                        if (s1 instanceof Comparable && s2 instanceof Comparable) {
                          return ((Comparable) s1).compareTo((Comparable) s2);
                        }
                        if (s1 != null && s2 != null) {
                          return s1.toString().compareTo(s2.toString());
                        } else if (s2 != null) {
                          return -1;
                        }
                        return 0;
                      }
                    }));
      }
    }

    return new BasePagingLoadResult(list, pgc.getOffset(), getCount(modelName, criteria));
  }