protected override IPredicate BuildPredicate(XPathNavigator predicateElement, bool inHead, bool resolveImmediatly)
        {
            IPredicate predicate;
            string predicateName = predicateElement.Name;
            string predicateValue = predicateElement.Value;

            switch(predicateName) {
                // --------- IND predicates --------
                case "ind":
                    if (predicateValue.ToLower().StartsWith("expr:")) {
                        if (inHead) {
                            if (resolveImmediatly) predicate = new Individual(Compilation.Evaluate(predicateValue));
                            else predicate = new Formula(Formula.FormulaResolutionType.NxBRE,
                                                         Binder,
                                                         predicateValue);
                        }
                        else {
                            predicate = new Function(Function.FunctionResolutionType.Binder,
                                                     predicateValue,
                                                     new ExpressionEvaluator(predicateValue),
                                                   	 String.Empty,
                                                  	 String.Empty);
                        }
                    }
                    else if (predicateValue.ToLower().StartsWith("nxbre:")) {
                        // NxBRE functions must follow this pattern: NxBRE:Function(uniqueargument)
                        string[] split = predicateValue.Split(Parameter.PARENTHESIS);
                        predicate = new Function(Function.FunctionResolutionType.NxBRE,
                                                 predicateValue,
                                                 null,
                                                                         split[0],
                                                                         split[1]);
                    }
                    else if (Binder == null) {
                        predicate = new Individual(predicateValue);
                    }
                    else if ((inHead) && (predicateValue.ToLower().StartsWith("binder:"))) {
                        predicate = new Formula(Formula.FormulaResolutionType.Binder,
                                                Binder,
                                                predicateValue);
                    }
                    else if ((inHead) && (predicateValue.EndsWith("()"))) {
                        predicate = new Formula(Formula.FormulaResolutionType.Binder,
                                                Binder,
                                                predicateValue);
                    }
                    else {
                        predicate = Binder.AnalyzeIndividualPredicate(new Individual(predicateValue));
                    }

                break;

            // --------- VAR predicates --------
            case "var":
                predicate = new Variable(predicateValue);
                break;

            // --------- UNKNOWN predicates --------
            default:
                throw new BREException("Unsupported predicate type: " + predicateName);
            }

            return predicate;
        }
        protected override IPredicate BuildPredicate(XPathNavigator predicateElement, bool inHead, bool resolveImmediatly)
        {
            IPredicate predicate;
            string predicateName = predicateElement.Name;
            string predicateValue = predicateElement.Value;

            switch(predicateName) {
                // --------- IND predicates --------
                case "Ind":
                    string predicateURI = predicateElement.GetAttribute("uri", String.Empty).ToLower();

                    switch(predicateURI) {
                        case "nxbre://expression":
                            if (inHead) {
                                if (resolveImmediatly) predicate = new Individual(Compilation.Evaluate(predicateValue));
                                else predicate = new Formula(Formula.FormulaResolutionType.NxBRE,
                                                             Binder,
                                                             predicateValue);
                            }
                            else {
                                predicate = new Function(Function.FunctionResolutionType.Binder,
                                                         predicateValue,
                                                         new ExpressionEvaluator(predicateValue),
                                                       	 String.Empty,
                                                      	 String.Empty);
                            }
                            break;

                        case "nxbre://operator":
                            // NxBRE operators must follow this pattern: operator(uniqueargument)
                            string[] split = predicateValue.Split(Parameter.PARENTHESIS);
                            predicate = new Function(Function.FunctionResolutionType.NxBRE,
                                                     predicateValue,
                                                     null,
                                                                             split[0],
                                                                             split[1]);
                            break;

                        case "nxbre://binder":
                            if (Binder == null) throw new BREException("No binder available for Individual: " + predicateValue);

                            if (inHead) predicate = new Formula(Formula.FormulaResolutionType.Binder,
                                                                            Binder,
                                                   							predicateValue);
                            else predicate = Binder.AnalyzeIndividualPredicate(new Individual(predicateValue));

                            break;

                        case "":
                            predicate = new Individual(predicateValue);
                            break;

                        default:
                            // there is a predicateURI but it is not recognized by the engine so we assimilate it as
                            // a web reference
                            predicate = new Individual(new HyperLink(predicateValue, predicateURI));
                            break;
                    }
                    break;

            // --------- VAR predicates --------
            case "Var":
                predicate = new Variable(predicateValue);
                break;

            // --------- DATA predicates --------
            case "Data":
                string schemaType = predicateElement.GetAttribute("type", "http://www.w3.org/2001/XMLSchema-instance");
                if (schemaType != String.Empty) {
                    // remove any preceding namespace, like in "xs:string"
                    if (schemaType.IndexOf(':')>=0) schemaType = schemaType.Split(':')[1];

                    // this is a strongly typed individual
                    predicate = new Individual(Schema.ToClr(predicateValue, schemaType), schemaType);
                }
                else {
                    // this is just a string based predicate, using Data was not so wise...
                    predicate = new Individual(predicateValue);
                }

                break;

            // --------- SLOT predicates --------
            case "slot":
                // the first child must be an Ind, we do not support other slot name holders
                if (predicateElement.MoveToFirstChild()) {
                    if (predicateElement.Name != "Ind") throw new BREException("Only Ind is accepted as a slot name holder");
                    string slotName = predicateElement.Value;
                    if (!predicateElement.MoveToNext()) throw new BREException("A slot should contain two children");
                    predicate = new Slot(slotName, BuildPredicate(predicateElement, inHead, resolveImmediatly));
                }
                else {
                    throw new BREException("A slot can not be empty");
                }

                break;

            // --------- UNKNOWN predicates --------
            default:
                throw new BREException("Unsupported predicate type: " + predicateName);
            }

            return predicate;
        }
		private Atom GetAtom(XPathNavigator atom, bool negative, bool inHead, bool resolveImmediatly) {
			ArrayList relationPredicates;
			XPathNodeIterator rel;
			XPathNodeIterator predicates;
			
			relationPredicates = new ArrayList();
			rel = atom.Select(GetXPathExpression("dl:_opr/dl:rel"));
			rel.MoveNext();
			String atomRelation = rel.Current.Value;
			
			predicates = atom.Select(GetXPathExpression("dl:ind | dl:var"));
			while(predicates.MoveNext()) {
				IPredicate predicate;
				string predicateValue = predicates.Current.Value;
				
				if (predicates.Current.Name == "ind") {
					if (predicateValue.ToLower().StartsWith("expr:")) {
						if (inHead) {
							if (resolveImmediatly) predicate = new Individual(Compilation.Evaluate(predicateValue));
							else predicate = new Formula(Formula.FormulaResolutionType.NxBRE,
							                             Binder,
							                             predicateValue);
						}
						else {
							predicate = new Function(Function.FunctionResolutionType.Binder,
							                         predicateValue,
							                         new ExpressionEvaluator(predicateValue),
							                       	 String.Empty,
							                      	 String.Empty);
						}
					}
					else if (predicateValue.ToLower().StartsWith("nxbre:")) {
						// NxBRE functions must follow this pattern: NxBRE:Function(uniqueargument)
						string[] split = predicateValue.Split(Parameter.PARENTHESIS);
						predicate = new Function(Function.FunctionResolutionType.NxBRE,
						                         predicateValue,
						                         null,
																		 split[0],
																		 split[1]);
					}
					else if (Binder == null)
						predicate = new Individual(predicateValue);
					else if ((inHead) && ((predicateValue.ToLower().StartsWith("binder:")) || (predicateValue.EndsWith("()"))))
						predicate = new Formula(Formula.FormulaResolutionType.Binder,
						                        Binder,
						                        predicateValue);
					else
						predicate = Binder.AnalyzeIndividualPredicate(new Individual(predicateValue));
				}
				else if (predicates.Current.Name == "var") {
					predicate = new Variable(predicateValue);
				}
				else
					throw new BREException("Unsupported predicate type: " + predicates.Current.Name);
				
				relationPredicates.Add(predicate);
			}
			
			// build the array of predicates
			IPredicate[] predicatesArray = (IPredicate[])relationPredicates.ToArray(typeof(IPredicate));
			
			// identify function based atom relations
			AtomFunction.RelationResolutionType resolutionType = AtomFunction.RelationResolutionType.None;
			if (atomRelation.ToLower().StartsWith("nxbre:"))
				resolutionType = AtomFunction.RelationResolutionType.NxBRE;
			else if ((atomRelation.ToLower().StartsWith("binder:")) || (atomRelation.EndsWith("()")))
				resolutionType = AtomFunction.RelationResolutionType.Binder;
			else if (atomRelation.ToLower().StartsWith("expr:"))
				resolutionType = AtomFunction.RelationResolutionType.Expression;
			
			if ((resolutionType == AtomFunction.RelationResolutionType.NxBRE) ||
			    (resolutionType == AtomFunction.RelationResolutionType.Binder))
				return new AtomFunction(resolutionType,
				                        negative,
				                        Binder,
				                        atomRelation,
					          	  				predicatesArray);
			
			else if (resolutionType == AtomFunction.RelationResolutionType.Expression)
				return new AtomFunction(resolutionType,
				                        negative,
				                        new ExpressionRelater(atomRelation, predicatesArray),
				                        atomRelation,
					          	  				predicatesArray);
			else
				return new Atom(negative,
	              				atomRelation,
	          	  				predicatesArray);
		}