diff --git a/src/code/type.m4 b/src/code/type.m4
index b5c6e17259161bf1b47ee37052ff15c2cff12ebf..7844fe3d08734fbebc8e746ff5daed746da83aed 100644
--- a/src/code/type.m4
+++ b/src/code/type.m4
@@ -311,6 +311,10 @@ inline void reset_func($1)
     (type_name($1)& x);
 inline int if_$1_length
     (const type_name($1) x);
+int if_$1_`index'
+    (const type_name($1) x, const type_name($2) e);
+inline type_name(boolean) if_$1_in
+    (const type_name($2) e, const type_name($1) x);
 `#define' iterate_func($1)(x)\
 array_iterate($2,decr($4))')
 
@@ -354,6 +358,18 @@ inline void reset_func($1)
 inline int if_$1_length
     (const type_name($1)) {
   return $3;
+}
+int if_$1_`index'
+    (const type_name($1) x, const type_name($2) e) {
+  int idx = -1;
+  for(int i=0;i<$3 && idx<0;i++)
+    if (compare_func($2)(x[i],e)==0)
+      idx = i;
+  return idx;
+}
+inline type_name(boolean) if_$1_in
+    (const type_name($2) e, const type_name($1) x) {
+  return if_$1_`index'(x,e)==-1 ? if_boolean_false : if_boolean_true;
 }')
 
 
@@ -394,8 +410,8 @@ type_name($1) if_$1_remove
     (const type_name($1) x, const int k);
 type_name($1) if_$1_insert
     (const type_name($1) x, const int k, const type_name($2) e);
-int if_$1_`index'
-    (const type_name($1) x, const type_name($2) e);')
+type_name(boolean) if_$1_in
+    (const type_name($2) e, const type_name($1) x);')
 
 # string_type_impl(T,T1,n)
 
@@ -437,7 +453,6 @@ inline void reset_func($1)
   for(int i=0;i<$3;i++)
     reset_func($2)(x.elem[i]);
 }
-
 inline int if_$1_length
     (const type_name($1) x) {
   return x.length;
@@ -515,7 +530,12 @@ int if_$1_`index'
     if (compare_func($2)(x.elem[i],e)==0)
       idx = i;
   return idx;
-}')
+}
+inline type_name(boolean) if_$1_in
+    (const type_name($2) e, const type_name($1) x) {
+  return if_$1_`index'(x,e) == -1 ? if_boolean_false : if_boolean_true;
+}
+')
 
 
 # ----------------------------------------------------------------#
diff --git a/src/model/expression.C b/src/model/expression.C
index b5c3353065377e92e2476571d1f3def8bb48b71c..b33f6b86e4625ae7a2b6e60a9588d6c69de24719 100644
--- a/src/model/expression.C
+++ b/src/model/expression.C
@@ -280,8 +280,10 @@ void IfCallExpression::PreCompile() {
         m_pType = t0;
       break;
     case INDEX:
-      if (t0->IsString() && 
-          t1->Match(((IfStringType*) t0)->GetElement()))
+      if ((t0->IsString() && 
+           t1->Match(((IfStringType*) t0)->GetElement())) ||
+	  (t0->IsArray() &&
+	   t1->Match(((IfArrayType*) t1)->GetElement())))
         m_pType = integer;
       break;
     case OBS_QLENGTH:
@@ -1180,7 +1182,9 @@ IfBinaryExpression::OPERATOR[] = {
   {  "=",    "eq", 4, 2}, 
   { "<>",    "ne", 4, 2}, 
   {"and",   "and", 5, 2},
-  { "or",    "or", 6, 2}
+  { "or",    "or", 6, 2},
+  {"xor",   "xor", 6, 2},
+  { "in",    "in", 7, 2}
 };
 
 IfBinaryExpression::IfBinaryExpression(IfExpression* Left,
@@ -1256,12 +1260,19 @@ void IfBinaryExpression::PreCompile() {
           tl->GetBase() == tr->GetBase())
         m_pType = boolean;
       break;
-    case AND: case OR:
+    case AND: case OR: case XOR:
       if (tl->Match(boolean) &&
           tr->Match(boolean))
         m_pType = boolean;
       break;
-    }
+     case IN:
+      if ((tr->IsArray() &&
+	   tl->Match(((IfArrayType*) tr)->GetElement())) ||
+	  (tr->IsString() &&
+	   tl->Match(((IfStringType*) tr)->GetElement())))
+	m_pType = boolean;
+      break;
+   }
   
   /// time inference
 
@@ -1291,6 +1302,9 @@ void IfBinaryExpression::Code(FILE* file) const {
     else if (tl->Match(integer) || tr->Match(integer) || tl->Match(pid) || tr->Match(pid))
       type = integer;
     break;
+  case IN:
+    type = tr;
+    break;
   default:
     type = m_pType;
   }
diff --git a/src/model/expression.h b/src/model/expression.h
index 7c4079b6cf2dfefda284277258e6db586894db79..6a1f4c6dd4e80e2918a8bc08ffc82748d6d8e6a7 100644
--- a/src/model/expression.h
+++ b/src/model/expression.h
@@ -504,7 +504,8 @@ class IfBinaryExpression : public IfExpression {
     LT, LE, GE, GT, 
     EQ, NE, 
     AND, 
-    OR,
+    OR, XOR,
+    IN
   };
 
  public:
diff --git a/src/model/if.lex.l b/src/model/if.lex.l
index 4a670bcc68f5051e2c742f1d21c603a0c71dba48..d99bdea974a3185871d856973b77a9bd3fece86b 100644
--- a/src/model/if.lex.l
+++ b/src/model/if.lex.l
@@ -172,6 +172,7 @@ void            { return VOID_K; }
 with            { return WITH_K; }
 when            { return WHEN_K; }
 while           { return WHILE_K; }
+xor             { return XOR_K; }
 
 
 
diff --git a/src/model/if.yacc.y b/src/model/if.yacc.y
index e055253d91a6353b0b1f4e76affa3d8b8768f850..e8e1c925b6e0bde002720e7387bafae2a589964c 100644
--- a/src/model/if.yacc.y
+++ b/src/model/if.yacc.y
@@ -291,7 +291,7 @@ void yywarning(const char* msg) {
 %token VAR_K PUBLIC_K PRIVATE_K
 
 %token VOID_K NOT_K UMIN_K ACTIVE_K TIMEVAL_K LENGTH_K
-%token LE_K GE_K NE_K AND_K OR_K 
+%token LE_K GE_K NE_K AND_K OR_K XOR_K
 %token INSTATE_K
 %token INSTANCEOF_K
 
@@ -327,7 +327,7 @@ void yywarning(const char* msg) {
 
 %left ','
 
-%left OR_K
+%left OR_K XOR_K
 
 %left AND_K
 
@@ -616,6 +616,10 @@ expression :
     { $$ = new IfBinaryExpression($1, IfBinaryExpression::AND, $3); }
 | expression OR_K expression 
     { $$ = new IfBinaryExpression($1, IfBinaryExpression::OR, $3); }
+| expression XOR_K expression
+    { $$ = new IfBinaryExpression($1, IfBinaryExpression::XOR, $3); }
+| expression IN_K expression
+    { $$ = new IfBinaryExpression($1, IfBinaryExpression::IN, $3); }
 | expression '?' expression ':' expression 
     { $$ = new IfTernaryExpression(IfTernaryExpression::CONDITIONAL, $1, $3, $5); }
 | '(' expression ')' 
diff --git a/src/simulator/base.i b/src/simulator/base.i
index 14028662126f18c608246cbda9c780650b101444..2fccdbcb9dd5ea2873cc4c0dfe0f127c3f5f3b2b 100644
--- a/src/simulator/base.i
+++ b/src/simulator/base.i
@@ -68,6 +68,8 @@
 
 #define if_boolean_or(x,y) (x)||(y)
 
+#define if_boolean_xor(x,y) ((x)&&!(y))||(!(x)&&(y))
+
 
 #define if_boolean_eq(x,y) (x)==(y)