//---------------------------------------------------------------------------
void SemanticAnalysis::transform(const SPARQLParser& input,QueryGraph& output)
   // Perform the transformation
{
   output.clear();

   if (!transformSubquery(dict,diffIndex,input.getPatterns(),output.getQuery())) {
      // A constant could not be resolved. This will produce an empty result
      output.markAsKnownEmpty();
      return;
   }

   // Compute the edges
   output.constructEdges();


   // Add the projection entry
   for (SPARQLParser::projection_iterator iter=input.projectionBegin(),limit=input.projectionEnd();iter!=limit;++iter){
      output.addProjection(*iter);
   }

   // Add the path projection entry
   for (SPARQLParser::projection_iterator iter=input.pathprojectionBegin(), limit=input.pathprojectionEnd(); iter!=limit;++iter){
	  output.addProjection(*iter);
   }

   // Set the duplicate handling
   switch (input.getProjectionModifier()) {
      case SPARQLParser::Modifier_None: output.setDuplicateHandling(QueryGraph::AllDuplicates); break;
      case SPARQLParser::Modifier_Distinct: output.setDuplicateHandling(QueryGraph::NoDuplicates); break;
      case SPARQLParser::Modifier_Reduced: output.setDuplicateHandling(QueryGraph::ReducedDuplicates); break;
      case SPARQLParser::Modifier_Count: output.setDuplicateHandling(QueryGraph::CountDuplicates); break;
      case SPARQLParser::Modifier_Duplicates: output.setDuplicateHandling(QueryGraph::ShowDuplicates); break;
   }

   // Set the query form
   switch (input.getQueryForm()){
      case SPARQLParser::Select: output.setQueryForm(QueryGraph::Select); break;
      case SPARQLParser::Describe: output.setQueryForm(QueryGraph::Describe); break;
      case SPARQLParser::Ask: case SPARQLParser::Construct: break;
   }

   // Order by clause
   for (SPARQLParser::order_iterator iter=input.orderBegin(),limit=input.orderEnd();iter!=limit;++iter) {
      QueryGraph::Order o;
      if (~(*iter).id) {
         if (!binds(input.getPatterns(),(*iter).id))
            continue;
         o.id=(*iter).id;
      } else {
         o.id=~0u;
      }
      o.descending=(*iter).descending;
      output.addOrder(o);
   }

   // Set the limit
   output.setLimit(input.getLimit());
}