Merge "Mobicore:  Update managed branches."
diff --git a/Android.mk b/Android.mk
old mode 100644
new mode 100755
diff --git a/common/MobiCore/inc/TlCm/2.0/cmp.h b/common/MobiCore/inc/TlCm/2.0/cmp.h
index 7ad0de4..8b4abf7 100755
--- a/common/MobiCore/inc/TlCm/2.0/cmp.h
+++ b/common/MobiCore/inc/TlCm/2.0/cmp.h
@@ -12,7 +12,7 @@
  * Various components need access to (sub-)structures defined and used by CMP
  * 2.0. These common definitions are made available through this header file.
  *
- * Copyright © Trustonic Limited 2013.
+ * Copyright © Trustonic Limited 2013.
  *
  * All rights reserved.
  * 
diff --git a/common/MobiCore/inc/TlCm/2.0/tlCmApi.h b/common/MobiCore/inc/TlCm/2.0/tlCmApi.h
index a458c40..ef58d99 100755
--- a/common/MobiCore/inc/TlCm/2.0/tlCmApi.h
+++ b/common/MobiCore/inc/TlCm/2.0/tlCmApi.h
@@ -6,7 +6,7 @@
  * The CMTL (Content Management Trustlet) is responsible for implementing
  * CMP 2.0 commands and generating approriate CMP 2.0 responses.
  *
- * Copyright © Trustonic Limited 2013.
+ * Copyright © Trustonic Limited 2013.
  *
  * All rights reserved.
  * 
diff --git a/common/MobiCore/inc/TlCm/3.0/cmp.h b/common/MobiCore/inc/TlCm/3.0/cmp.h
index e617aea..1712865 100755
--- a/common/MobiCore/inc/TlCm/3.0/cmp.h
+++ b/common/MobiCore/inc/TlCm/3.0/cmp.h
@@ -12,7 +12,7 @@
  * Various components need access to (sub-)structures defined and used by CMP;
  * these common definitions are made available through this header file.
  *
- * Copyright © Trustonic Limited 2013.
+ * Copyright © Trustonic Limited 2013.
  *
  * All rights reserved.
  * 
diff --git a/common/MobiCore/inc/TlCm/3.0/cmpMap.h b/common/MobiCore/inc/TlCm/3.0/cmpMap.h
index 02d2b33..28f6286 100755
--- a/common/MobiCore/inc/TlCm/3.0/cmpMap.h
+++ b/common/MobiCore/inc/TlCm/3.0/cmpMap.h
@@ -12,7 +12,7 @@
  * Various components need access to (sub-)structures defined and used by CMP;
  * these common definitions are made available through this header file.
  *
- * Copyright © Trustonic Limited 2013.
+ * Copyright © Trustonic Limited 2013.
  *
  * All rights reserved.
  * 
diff --git a/common/MobiCore/inc/TlCm/3.0/tlCmApi.h b/common/MobiCore/inc/TlCm/3.0/tlCmApi.h
index 8020fad..173bd20 100755
--- a/common/MobiCore/inc/TlCm/3.0/tlCmApi.h
+++ b/common/MobiCore/inc/TlCm/3.0/tlCmApi.h
@@ -6,7 +6,7 @@
  * The CMTL (Content Management Trustlet) is responsible for implementing
  * CMP commands and generating approriate CMP responses.
  *
- * Copyright © Trustonic Limited 2013.
+ * Copyright © Trustonic Limited 2013.
  *
  * All rights reserved.
  * 
diff --git a/common/MobiCore/inc/TlCm/cmpCommon.h b/common/MobiCore/inc/TlCm/cmpCommon.h
index 28ff083..721c486 100755
--- a/common/MobiCore/inc/TlCm/cmpCommon.h
+++ b/common/MobiCore/inc/TlCm/cmpCommon.h
@@ -9,7 +9,7 @@
  * Various components need access to (sub-)structures defined and used by CMP.
  * These common definitions are made available through this header file.
  *
- * Copyright © Trustonic Limited 2013.
+ * Copyright © Trustonic Limited 2013.
  *
  * All rights reserved.
  * 
diff --git a/common/MobiCore/inc/TlCm/tlCmApiCommon.h b/common/MobiCore/inc/TlCm/tlCmApiCommon.h
index 56f6531..5e6d5df 100755
--- a/common/MobiCore/inc/TlCm/tlCmApiCommon.h
+++ b/common/MobiCore/inc/TlCm/tlCmApiCommon.h
@@ -6,7 +6,7 @@
  * The CMTL (Content Management Trustlet) is responsible for implementing
  * CMP commands and generating approriate CMP responses.
  *
- * Copyright © Trustonic Limited 2013.
+ * Copyright © Trustonic Limited 2013.
  *
  * All rights reserved.
  * 
diff --git a/common/MobiCore/inc/TlCm/tlCmError.h b/common/MobiCore/inc/TlCm/tlCmError.h
index 46e1268..c9d30ee 100644
--- a/common/MobiCore/inc/TlCm/tlCmError.h
+++ b/common/MobiCore/inc/TlCm/tlCmError.h
@@ -5,7 +5,7 @@
  * CMTL (Content Management Trustlet) error return code definitions.
  * Definition of all possible CMTL error return codes.
  *
- * Copyright © Trustonic Limited 2013.
+ * Copyright © Trustonic Limited 2013.
  *
  * All rights reserved.
  * 
diff --git a/common/MobiCore/inc/TlCm/tlCmUuid.h b/common/MobiCore/inc/TlCm/tlCmUuid.h
index de582e8..60d8e18 100644
--- a/common/MobiCore/inc/TlCm/tlCmUuid.h
+++ b/common/MobiCore/inc/TlCm/tlCmUuid.h
@@ -3,7 +3,7 @@
  * @file
  * Content management trustlet UUID definition.
  *
- * Copyright © Trustonic Limited 2013.
+ * Copyright © Trustonic Limited 2013.
  *
  * All rights reserved.
  * 
diff --git a/common/MobiCore/inc/TlCm/version.h b/common/MobiCore/inc/TlCm/version.h
index 4a59d6e..bcb4d34 100644
--- a/common/MobiCore/inc/TlCm/version.h
+++ b/common/MobiCore/inc/TlCm/version.h
@@ -1,6 +1,6 @@
 /** @addtogroup CMP
  *
- * Copyright © Trustonic Limited 2013.
+ * Copyright © Trustonic Limited 2013.
  *
  * All rights reserved.
  * 
diff --git a/common/MobiCore/inc/mcContainer.h b/common/MobiCore/inc/mcContainer.h
index ca56b8e..9edcc1a 100644
--- a/common/MobiCore/inc/mcContainer.h
+++ b/common/MobiCore/inc/mcContainer.h
@@ -2,32 +2,36 @@
  * @ingroup  MC_DATA_TYPES
  * @{
  *
- * <!-- Copyright Trustonic 2013-2014 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
+ * Copyright © Trustonic Limited 2013
+ * 
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ * 
+ *   1. Redistributions of source code must retain the above copyright notice, this 
+ *      list of conditions and the following disclaimer.
+ * 
+ *   2. Redistributions in binary form must reproduce the above copyright notice, 
+ *      this list of conditions and the following disclaimer in the documentation 
+ *     and/or other materials provided with the distribution.
+ * 
+ *   3. Neither the name of the Trustonic Limited nor the names of its contributors 
+ *      may be used to endorse or promote products derived from this software 
+ *      without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */ 
+ 
 #ifndef MC_CONTAINER_H_
 #define MC_CONTAINER_H_
 
diff --git a/common/MobiCore/inc/mcDriverId.h b/common/MobiCore/inc/mcDriverId.h
index 96f4bc4..25fd32c 100644
--- a/common/MobiCore/inc/mcDriverId.h
+++ b/common/MobiCore/inc/mcDriverId.h
@@ -2,31 +2,34 @@
  * @file
  * Driver ID definition.
  *
- * <!-- Copyright Trustonic 2013-2014 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Copyright © Trustonic Limited 2013
+ * 
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ * 
+ *   1. Redistributions of source code must retain the above copyright notice, this 
+ *      list of conditions and the following disclaimer.
+ * 
+ *   2. Redistributions in binary form must reproduce the above copyright notice, 
+ *      this list of conditions and the following disclaimer in the documentation 
+ *     and/or other materials provided with the distribution.
+ * 
+ *   3. Neither the name of the Trustonic Limited nor the names of its contributors 
+ *      may be used to endorse or promote products derived from this software 
+ *      without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef RTMDRVID_H_
diff --git a/common/MobiCore/inc/mcLoadFormat.h b/common/MobiCore/inc/mcLoadFormat.h
index 19c5415..9c97cbe 100644
--- a/common/MobiCore/inc/mcLoadFormat.h
+++ b/common/MobiCore/inc/mcLoadFormat.h
@@ -10,31 +10,35 @@
  * MobiCore Load Format declarations.
  *
  * Holds the definitions for the layout of MobiCore Trustlet Blob.
- * <!-- Copyright Trustonic 2013-2014 -->
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Copyright © Trustonic Limited 2013
+ * 
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ * 
+ *   1. Redistributions of source code must retain the above copyright notice, this 
+ *      list of conditions and the following disclaimer.
+ * 
+ *   2. Redistributions in binary form must reproduce the above copyright notice, 
+ *      this list of conditions and the following disclaimer in the documentation 
+ *     and/or other materials provided with the distribution.
+ * 
+ *   3. Neither the name of the Trustonic Limited nor the names of its contributors 
+ *      may be used to endorse or promote products derived from this software 
+ *      without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #ifndef MCLOADFORMAT_H_
 #define MCLOADFORMAT_H_
@@ -44,8 +48,8 @@
 #include "mcDriverId.h"
 
 #define MCLF_VERSION_MAJOR   2
-#define MCLF_VERSION_MINOR   2
-#define MCLF_VERSION_MINOR_CURRENT   1
+#define MCLF_VERSION_MINOR   3
+#define MCLF_VERSION_MINOR_CURRENT   3
 
 #define MC_SERVICE_HEADER_MAGIC_BE         ((uint32_t)('M'|('C'<<8)|('L'<<16)|('F'<<24))) /**< "MCLF" in big endian integer representation */
 #define MC_SERVICE_HEADER_MAGIC_LE         ((uint32_t)(('M'<<24)|('C'<<16)|('L'<<8)|'F')) /**< "MCLF" in little endian integer representation */
diff --git a/common/MobiCore/inc/mcRootid.h b/common/MobiCore/inc/mcRootid.h
index cc2f143..4d5630b 100644
--- a/common/MobiCore/inc/mcRootid.h
+++ b/common/MobiCore/inc/mcRootid.h
@@ -3,31 +3,34 @@
  *
  * Global definition of root ID.
  *
- * <!-- Copyright Trustonic 2013-2014 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Copyright © Trustonic Limited 2013
+ * 
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ * 
+ *   1. Redistributions of source code must retain the above copyright notice, this 
+ *      list of conditions and the following disclaimer.
+ * 
+ *   2. Redistributions in binary form must reproduce the above copyright notice, 
+ *      this list of conditions and the following disclaimer in the documentation 
+ *     and/or other materials provided with the distribution.
+ * 
+ *   3. Neither the name of the Trustonic Limited nor the names of its contributors 
+ *      may be used to endorse or promote products derived from this software 
+ *      without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * @ingroup  MC_DATA_TYPES
  * @{
diff --git a/common/MobiCore/inc/mcSo.h b/common/MobiCore/inc/mcSo.h
index e5368cf..8281f45 100644
--- a/common/MobiCore/inc/mcSo.h
+++ b/common/MobiCore/inc/mcSo.h
@@ -2,31 +2,35 @@
  * @defgroup MC_DATA_TYPES MobiCore generic data types
  *
  * @addtogroup MC_SO mcSo - Secure objects definitions.
- * <!-- Copyright Trustonic 2013-2014 -->
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Copyright © Trustonic Limited 2013
+ * 
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ * 
+ *   1. Redistributions of source code must retain the above copyright notice, this 
+ *      list of conditions and the following disclaimer.
+ * 
+ *   2. Redistributions in binary form must reproduce the above copyright notice, 
+ *      this list of conditions and the following disclaimer in the documentation 
+ *     and/or other materials provided with the distribution.
+ * 
+ *   3. Neither the name of the Trustonic Limited nor the names of its contributors 
+ *      may be used to endorse or promote products derived from this software 
+ *      without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * @ingroup  MC_DATA_TYPES
  * @{
@@ -38,6 +42,7 @@
 
 #include "mcUuid.h"
 #include "mcSpid.h"
+#include "mcRootid.h"
 
 #define SO_USE_VERSION_22 1
 
@@ -94,6 +99,17 @@
     mcUuid_t uuid;
 } tlApiSpTrustletId_t;
 
+/** Service provider Trustlet id with specific RootId.
+ */
+typedef struct {
+    /** Service provider id. */
+    mcSpid_t spid;
+    /** Trustlet UUID. */
+    mcUuid_t uuid;
+    /** Trustlet RootId. */
+    mcRootid_t rootid;
+} tlApiSpTrustletIdEx_t;
+
 /** Secure object header v2.2.
  * A secure object header introduces a secure object.
  * Layout of a secure object:
diff --git a/common/MobiCore/inc/mcSpid.h b/common/MobiCore/inc/mcSpid.h
index e3f2d64..ea19e5e 100644
--- a/common/MobiCore/inc/mcSpid.h
+++ b/common/MobiCore/inc/mcSpid.h
@@ -1,31 +1,35 @@
 /**
  * @addtogroup MC_SPID mcSpid - service provider ID.
  *
- * <!-- Copyright Trustonic 2013-2014 -->
+ * Copyright © Trustonic Limited 2013
+ * 
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ * 
+ *   1. Redistributions of source code must retain the above copyright notice, this 
+ *      list of conditions and the following disclaimer.
+ * 
+ *   2. Redistributions in binary form must reproduce the above copyright notice, 
+ *      this list of conditions and the following disclaimer in the documentation 
+ *     and/or other materials provided with the distribution.
+ * 
+ *   3. Neither the name of the Trustonic Limited nor the names of its contributors 
+ *      may be used to endorse or promote products derived from this software 
+ *      without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  * @ingroup  MC_DATA_TYPES
  * @{
  */
diff --git a/common/MobiCore/inc/mcSuid.h b/common/MobiCore/inc/mcSuid.h
index af917bd..fa02f68 100644
--- a/common/MobiCore/inc/mcSuid.h
+++ b/common/MobiCore/inc/mcSuid.h
@@ -1,31 +1,34 @@
 /**
  * @addtogroup MC_SUID mcSuid - SoC unique ID.
  *
- * <!-- Copyright Trustonic 2013-2014 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Copyright © Trustonic Limited 2013
+ * 
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ * 
+ *   1. Redistributions of source code must retain the above copyright notice, this 
+ *      list of conditions and the following disclaimer.
+ * 
+ *   2. Redistributions in binary form must reproduce the above copyright notice, 
+ *      this list of conditions and the following disclaimer in the documentation 
+ *     and/or other materials provided with the distribution.
+ * 
+ *   3. Neither the name of the Trustonic Limited nor the names of its contributors 
+ *      may be used to endorse or promote products derived from this software 
+ *      without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * @ingroup  MC_DATA_TYPES
  * @{
diff --git a/common/MobiCore/inc/mcUuid.h b/common/MobiCore/inc/mcUuid.h
index 20cde66..7ac888c 100644
--- a/common/MobiCore/inc/mcUuid.h
+++ b/common/MobiCore/inc/mcUuid.h
@@ -1,31 +1,34 @@
 /**
  * @addtogroup MC_UUID mcUuid - Universally Unique Identifier.
  *
- * <!-- Copyright Trustonic 2013-2014 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Copyright © Trustonic Limited 2013
+ * 
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ * 
+ *   1. Redistributions of source code must retain the above copyright notice, this 
+ *      list of conditions and the following disclaimer.
+ * 
+ *   2. Redistributions in binary form must reproduce the above copyright notice, 
+ *      this list of conditions and the following disclaimer in the documentation 
+ *     and/or other materials provided with the distribution.
+ * 
+ *   3. Neither the name of the Trustonic Limited nor the names of its contributors 
+ *      may be used to endorse or promote products derived from this software 
+ *      without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * @ingroup  MC_DATA_TYPES
  * @{
diff --git a/common/MobiCore/inc/mcVersionHelper.h b/common/MobiCore/inc/mcVersionHelper.h
index e635889..fb6e563 100644
--- a/common/MobiCore/inc/mcVersionHelper.h
+++ b/common/MobiCore/inc/mcVersionHelper.h
@@ -2,31 +2,34 @@
  * @{
  * MobiCore Version Helper Macros
  *
- * <!-- Copyright Trustonic 2013-2014 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Copyright © Trustonic Limited 2013
+ * 
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ * 
+ *   1. Redistributions of source code must retain the above copyright notice, this 
+ *      list of conditions and the following disclaimer.
+ * 
+ *   2. Redistributions in binary form must reproduce the above copyright notice, 
+ *      this list of conditions and the following disclaimer in the documentation 
+ *     and/or other materials provided with the distribution.
+ * 
+ *   3. Neither the name of the Trustonic Limited nor the names of its contributors 
+ *      may be used to endorse or promote products derived from this software 
+ *      without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include <stdio.h>
 
diff --git a/common/MobiCore/inc/mcVersionInfo.h b/common/MobiCore/inc/mcVersionInfo.h
index cb8d214..9fb04da 100644
--- a/common/MobiCore/inc/mcVersionInfo.h
+++ b/common/MobiCore/inc/mcVersionInfo.h
@@ -2,31 +2,34 @@
  * @{
  * MobiCore Version Information
  *
- * <!-- Copyright Trustonic 2013-2014 -->
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Copyright © Trustonic Limited 2013
+ * 
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ * 
+ *   1. Redistributions of source code must retain the above copyright notice, this 
+ *      list of conditions and the following disclaimer.
+ * 
+ *   2. Redistributions in binary form must reproduce the above copyright notice, 
+ *      this list of conditions and the following disclaimer in the documentation 
+ *     and/or other materials provided with the distribution.
+ * 
+ *   3. Neither the name of the Trustonic Limited nor the names of its contributors 
+ *      may be used to endorse or promote products derived from this software 
+ *      without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef MCVERSIONINFO_H_
diff --git a/daemon/ClientLib/ClientLib.cpp b/daemon/ClientLib/ClientLib.cpp
index f79f729..8a17f23 100644
--- a/daemon/ClientLib/ClientLib.cpp
+++ b/daemon/ClientLib/ClientLib.cpp
@@ -329,6 +329,7 @@
     LOG_I("===%s()===", __FUNCTION__);
 
     do {
+        uint32_t handle = 0;
         CHECK_NOT_NULL(session);
         CHECK_NOT_NULL(uuid);
         CHECK_NOT_NULL(tci);
@@ -341,29 +342,39 @@
 
         // Get the device associated with the given session
         Device *device = resolveDeviceId(session->deviceId);
+        BulkBufferDescriptor *bulkBuf = NULL;
         CHECK_DEVICE(device);
 
         Connection *devCon = device->connection;
 
+        // First assume the TCI is a contiguous buffer
         // Get the physical address of the given TCI
         CWsm_ptr pWsm = device->findContiguousWsm(tci);
         if (pWsm == NULL) {
-            LOG_E("Could not resolve physical address of TCI");
-            mcResult = MC_DRV_ERR_WSM_NOT_FOUND;
-            break;
+            // Then assume it's a normal buffer that needs to be mapped
+            mcResult = device->mapBulkBuf(tci, len, &bulkBuf);
+            if (mcResult != MC_DRV_OK) {
+                bulkBuf = NULL;
+                LOG_E("Registering buffer failed. ret=%x", mcResult);
+                mcResult = MC_DRV_ERR_WSM_NOT_FOUND;;
+                break;
+            }
+            handle = bulkBuf->handle;
         }
-
-        if (pWsm->len < len) {
-            LOG_E("mcOpenSession(): length is more than allocated TCI");
-            mcResult = MC_DRV_ERR_TCI_GREATER_THAN_WSM;
-            break;
+        else {
+            if (pWsm->len < len) {
+                LOG_E("mcOpenSession(): length is more than allocated TCI");
+                mcResult = MC_DRV_ERR_TCI_GREATER_THAN_WSM;
+                break;
+            }
+            handle = pWsm->handle;
         }
 
         SEND_TO_DAEMON(devCon, MC_DRV_CMD_OPEN_SESSION,
                        session->deviceId,
                        *uuid,
-                       (uint32_t)0,
-                       (uint32_t)pWsm->handle,
+                       (uint32_t)(tci) & 0xFFF,
+                       (uint32_t)handle,
                        len);
 
         // Read command response
@@ -458,7 +469,10 @@
         // there is no payload.
 
         // Session has been established, new session object must be created
-        device->createNewSession(session->sessionId, sessionConnection);
+        Session *sessionObj = device->createNewSession(session->sessionId, sessionConnection);
+        // If the session tci was a mapped buffer then register it
+        if(bulkBuf)
+            sessionObj->addBulkBuf(bulkBuf);
 
         LOG_I(" Successfully opened session %d.", session->sessionId);
 
@@ -478,6 +492,7 @@
 //------------------------------------------------------------------------------
 __MC_CLIENT_LIB_API mcResult_t mcOpenTrustlet(
     mcSessionHandle_t  *session,
+    mcSpid_t           spid,
     uint8_t            *trustlet,
     uint32_t           tlen,
     uint8_t            *tci,
@@ -490,6 +505,7 @@
     LOG_I("===%s()===", __FUNCTION__);
 
     do {
+        uint32_t handle = 0;
         CHECK_NOT_NULL(session);
         CHECK_NOT_NULL(trustlet);
         CHECK_NOT_NULL(tci);
@@ -502,29 +518,40 @@
 
         // Get the device associated with the given session
         Device *device = resolveDeviceId(session->deviceId);
+        BulkBufferDescriptor *bulkBuf = NULL;
         CHECK_DEVICE(device);
 
         Connection *devCon = device->connection;
 
+        // First assume the TCI is a contiguous buffer
         // Get the physical address of the given TCI
         CWsm_ptr pWsm = device->findContiguousWsm(tci);
         if (pWsm == NULL) {
-            LOG_E("Could not resolve physical address of TCI");
-            mcResult = MC_DRV_ERR_WSM_NOT_FOUND;
-            break;
+            // Then assume it's a normal buffer that needs to be mapped
+            mcResult = device->mapBulkBuf(tci, len, &bulkBuf);
+            if (mcResult != MC_DRV_OK) {
+                bulkBuf = NULL;
+                LOG_E("Registering buffer failed. ret=%x", mcResult);
+                mcResult = MC_DRV_ERR_WSM_NOT_FOUND;;
+                break;
+            }
+            handle = bulkBuf->handle;
         }
-
-        if (pWsm->len < len) {
-            LOG_E("mcOpenSession(): length is more than allocated TCI");
-            mcResult = MC_DRV_ERR_TCI_GREATER_THAN_WSM;
-            break;
+        else {
+            if (pWsm->len < len) {
+                LOG_E("mcOpenSession(): length is more than allocated TCI");
+                mcResult = MC_DRV_ERR_TCI_GREATER_THAN_WSM;
+                break;
+            }
+            handle = pWsm->handle;
         }
 
         SEND_TO_DAEMON(devCon, MC_DRV_CMD_OPEN_TRUSTLET,
                        session->deviceId,
+                       spid,
                        (uint32_t)tlen,
-                       NULL,
-                       (uint32_t)pWsm->handle,
+                       (uint32_t)(tci) & 0xFFF,
+                       (uint32_t)handle,
                        len);
 
         // Send the full trustlet data
@@ -628,7 +655,10 @@
         // there is no payload.
 
         // Session has been established, new session object must be created
-        device->createNewSession(session->sessionId, sessionConnection);
+        Session *sessionObj = device->createNewSession(session->sessionId, sessionConnection);
+        // If the session tci was a mapped buffer then register it
+        if(bulkBuf)
+            sessionObj->addBulkBuf(bulkBuf);
 
         LOG_I(" Successfully opened session %d.", session->sessionId);
 
diff --git a/daemon/ClientLib/Device.cpp b/daemon/ClientLib/Device.cpp
index 9521b78..6b3bfbb 100644
--- a/daemon/ClientLib/Device.cpp
+++ b/daemon/ClientLib/Device.cpp
@@ -102,10 +102,11 @@
 
 
 //------------------------------------------------------------------------------
-void Device::createNewSession(uint32_t sessionId, Connection  *connection)
+Session *Device::createNewSession(uint32_t sessionId, Connection  *connection)
 {
     Session *session = new Session(sessionId, pMcKMod, connection);
     sessionList.push_back(session);
+    return session;
 }
 
 
@@ -228,4 +229,28 @@
     return pWsm;
 }
 
+
+//------------------------------------------------------------------------------
+mcResult_t Device::mapBulkBuf(addr_t buf, uint32_t len, BulkBufferDescriptor **blkBuf)
+{
+    addr_t pPhysWsmL2;
+    uint32_t handle;
+
+    *blkBuf = NULL;
+
+    // Prepare the interface structure for memory registration in Kernel Module
+    mcResult_t ret = pMcKMod->registerWsmL2(buf, len, 0, &handle, &pPhysWsmL2);
+    if (ret != MC_DRV_OK) {
+        LOG_V(" mcKMod->registerWsmL2() failed with %x", ret);
+        return ret;
+    }
+
+    LOG_V(" addBulkBuf - Handle of L2 Table = %u", handle);
+
+    // Create new descriptor - secure virtual virtual set to 0, unknown!
+    *blkBuf = new BulkBufferDescriptor(buf, 0x0, len, handle, pPhysWsmL2);
+
+    return MC_DRV_OK;
+}
+
 /** @} */
diff --git a/daemon/ClientLib/Device.h b/daemon/ClientLib/Device.h
index 5170d6e..d9a5741 100644
--- a/daemon/ClientLib/Device.h
+++ b/daemon/ClientLib/Device.h
@@ -93,8 +93,9 @@
      * Add a session to the device.
      * @param sessionId session ID
      * @param connection session connection
+     * @return Session object created
      */
-    void createNewSession(
+    Session *createNewSession(
         uint32_t    sessionId,
         Connection  *connection
     );
@@ -148,6 +149,19 @@
         addr_t  virtAddr
     );
 
+    /**
+     * Map a buffer from tlc VA to TL(Create L2 table for the buffer
+     * @param buf The virtual address of hte buffer
+     * @param len The length of the buffer
+     * @param blkBuf The buffer object created
+     * @return MC_DRV_OK if successful.
+     */
+    mcResult_t mapBulkBuf(
+        addr_t buf,
+        uint32_t len,
+        BulkBufferDescriptor **blkBuf
+    );
+
 };
 
 #endif /* DEVICE_H_ */
diff --git a/daemon/ClientLib/Session.cpp b/daemon/ClientLib/Session.cpp
index 3a85036..9f68984 100644
--- a/daemon/ClientLib/Session.cpp
+++ b/daemon/ClientLib/Session.cpp
@@ -142,6 +142,14 @@
 }
 
 //------------------------------------------------------------------------------
+void Session::addBulkBuf(BulkBufferDescriptor *blkBuf)
+{
+    if(blkBuf)
+        // Add to vector of descriptors
+        bulkBufferDescriptors.push_back(blkBuf);
+}
+
+//------------------------------------------------------------------------------
 uint32_t Session::getBufHandle(addr_t sVirtAddr)
 {
     LOG_V("getBufHandle(): Virtual Address = 0x%X", (unsigned int) virtAddr);
diff --git a/daemon/ClientLib/Session.h b/daemon/ClientLib/Session.h
index 76d2ccd..f24d6ce 100644
--- a/daemon/ClientLib/Session.h
+++ b/daemon/ClientLib/Session.h
@@ -120,6 +120,16 @@
     mcResult_t addBulkBuf(addr_t buf, uint32_t len, BulkBufferDescriptor **blkBuf);
 
     /**
+     * Just register the buffer previously created to the session
+     *
+     * @attention The virtual address can only be added one time. If the virtual address already exist, MC_DRV_ERR_BUFFER_ALREADY_MAPPED is returned.
+     *
+     * @param blkBuf pointer of the actual Bulk buffer descriptor with all address information.
+     *
+     */
+    void addBulkBuf(BulkBufferDescriptor *blkBuf);
+
+    /**
      * Remove address information of additional bulk buffer memory from session and
      * unregister virtual memory in kernel module
      *
diff --git a/daemon/ClientLib/public/MobiCoreDriverApi.h b/daemon/ClientLib/public/MobiCoreDriverApi.h
index 8f4644f..64f369e 100644
--- a/daemon/ClientLib/public/MobiCoreDriverApi.h
+++ b/daemon/ClientLib/public/MobiCoreDriverApi.h
@@ -13,8 +13,8 @@
  *
  * @image html DoxyOverviewDrvApi500x.png
  * @image latex DoxyOverviewDrvApi500x.png "MobiCore Overview" width=12cm
- *
- * <!-- Copyright Trustonic 2013-2014 -->
+ */
+/* <!-- Copyright Trustonic 2013-2014 -->
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -54,6 +54,7 @@
 #include <stdbool.h>
 
 #include "mcUuid.h"
+#include "mcSpid.h"
 #include "mcVersionInfo.h"
 
 /*
@@ -244,6 +245,7 @@
  * Waits till the MobiCore responses with the new session ID (stored in the MCP buffer).
  *
  * @param [in,out] session On success, the session data will be returned. Note that session.deviceId has to be the device id of an opened device.
+ * @param [in] spid Service Provider ID(for Service provider trustlets otherwise ignored)
  * @param [in] trustlet memory buffer containing the trustlet binary
  * @param [in] tlen length of the memory buffer containing the trustlet
  * @param [in] tci TCI buffer for communicating with the trustlet.
@@ -259,6 +261,7 @@
  */
 __MC_CLIENT_LIB_API mcResult_t mcOpenTrustlet(
     mcSessionHandle_t  *session,
+    mcSpid_t           spid,
     uint8_t            *trustlet,
     uint32_t           tLen,
     uint8_t            *tci,
diff --git a/daemon/Common/Connection.cpp b/daemon/Common/Connection.cpp
index 3debdc4..7468d4b 100644
--- a/daemon/Common/Connection.cpp
+++ b/daemon/Common/Connection.cpp
@@ -38,6 +38,7 @@
 
 #include "Connection.h"
 #include <sys/ioctl.h>
+#include <sys/socket.h>
 #include <poll.h>
 
 //#define LOG_VERBOSE
@@ -100,6 +101,7 @@
         LOG_ERRNO("connect()");
         return false;
     }
+    
     return true;
 }
 
@@ -229,4 +231,17 @@
     return true;
 }
 
+//------------------------------------------------------------------------------
+bool Connection::getPeerCredentials(struct ucred &cr)
+{
+    struct ucred cred;
+    int len = sizeof (cred);
+    assert(socketDescriptor != -1);
+    getsockopt(socketDescriptor, SOL_SOCKET, SO_PEERCRED, &cred, &len);
+    if (len == sizeof(cred)) {
+        cr = cred;
+        return true;
+    }
+    return false;
+}
 /** @} */
diff --git a/daemon/Common/Connection.h b/daemon/Common/Connection.h
index 42616f0..606c039 100644
--- a/daemon/Common/Connection.h
+++ b/daemon/Common/Connection.h
@@ -112,6 +112,13 @@
      */
     virtual bool isConnectionAlive(void);
 
+    /*
+     * Retrieve the peer's credentials(uid, pid, gid)
+     *
+     * @return true if connection peers could be retrieved
+     */
+    virtual bool getPeerCredentials(struct ucred &cr);
+
 };
 
 typedef std::list<Connection *>         connectionList_t;
diff --git a/daemon/Daemon/Device/MobiCoreDevice.cpp b/daemon/Daemon/Device/MobiCoreDevice.cpp
index b741268..59ea36c 100644
--- a/daemon/Daemon/Device/MobiCoreDevice.cpp
+++ b/daemon/Daemon/Device/MobiCoreDevice.cpp
@@ -86,6 +86,7 @@
         unlockWsmL2(pWsm->handle);
         pWsm = session->popBulkBuff();
     }
+    LOG_I("Finished unlocking session buffers!");
 }
 //------------------------------------------------------------------------------
 void MobiCoreDevice::removeTrustletSession(uint32_t sessionId)
@@ -251,17 +252,33 @@
     loadDataOpenSession_ptr         pLoadDataOpenSession,
     uint32_t                        tciHandle,
     uint32_t                        tciLen,
+    uint32_t                        tciOffset,
     mcDrvRspOpenSessionPayload_ptr  pRspOpenSessionPayload)
 {
     do {
         addr_t tci;
         uint32_t len;
 
-        if (!findContiguousWsm(tciHandle, &tci, &len)) {
+        // Check if we have a cont WSM or normal one
+        if (findContiguousWsm(tciHandle, deviceConnection->socketDescriptor, &tci, &len)) {
+            mcpMessage->cmdOpen.wsmTypeTci = WSM_CONTIGUOUS;
+            mcpMessage->cmdOpen.adrTciBuffer = (uint32_t)(tci);
+            mcpMessage->cmdOpen.ofsTciBuffer = 0;
+        }
+        else if((tci = findWsmL2(tciHandle, deviceConnection->socketDescriptor))) {
+            // We don't actually care about the len as the L2 table mapping is done
+            // and the TL will segfault if it's trying to access non-allocated memory
+            len = tciLen;
+            mcpMessage->cmdOpen.wsmTypeTci = WSM_L2;
+            mcpMessage->cmdOpen.adrTciBuffer = (uint32_t)(tci);
+            mcpMessage->cmdOpen.ofsTciBuffer = tciOffset;
+        }
+        else {
             LOG_E("Failed to find contiguous WSM %u", tciHandle);
             return MC_DRV_ERR_DAEMON_WSM_HANDLE_NOT_FOUND;
         }
 
+
         if (!lockWsmL2(tciHandle)) {
             LOG_E("Failed to lock contiguous WSM %u", tciHandle);
             return MC_DRV_ERR_DAEMON_WSM_HANDLE_NOT_FOUND;
@@ -277,9 +294,6 @@
         // Write MCP open message to buffer
         mcpMessage->cmdOpen.cmdHeader.cmdId = MC_MCP_CMD_OPEN_SESSION;
         mcpMessage->cmdOpen.uuid = pLoadDataOpenSession->tlHeader->mclfHeaderV2.uuid;
-        mcpMessage->cmdOpen.wsmTypeTci = WSM_CONTIGUOUS;
-        mcpMessage->cmdOpen.adrTciBuffer = (uint32_t)(tci);
-        mcpMessage->cmdOpen.ofsTciBuffer = 0;
         mcpMessage->cmdOpen.lenTciBuffer = tciLen;
         LOG_I(" Using phys=%p, len=%d as TCI buffer", (addr_t)tci, tciLen);
 
@@ -418,10 +432,9 @@
 
     return MC_DRV_OK;
 }
+
+//------------------------------------------------------------------------------
 /**
- * TODO-2012-09-19-haenellu: Do some more checks here, otherwise rogue clientLib
- * can close sessions from different TLCs. That is, deviceConnection is ignored below.
- *
  * Need connection as well as according session ID, so that a client can not
  * close sessions not belonging to him.
  */
@@ -433,6 +446,12 @@
         return MC_DRV_ERR_DAEMON_UNKNOWN_SESSION;
     }
 
+    /* The connection does not own this trustlet session */
+    if (ts->deviceConnection != deviceConnection) {
+        LOG_E("no session found with id=%d", sessionId);
+        return MC_DRV_ERR_DAEMON_UNKNOWN_SESSION;
+    }
+
     uint32_t mcRet = closeSession(sessionId);
     if (mcRet != MC_DRV_OK) {
         return mcRet;
@@ -447,7 +466,7 @@
 
 
 //------------------------------------------------------------------------------
-mcResult_t MobiCoreDevice::mapBulk(uint32_t sessionId, uint32_t handle, uint32_t pAddrL2,
+mcResult_t MobiCoreDevice::mapBulk(Connection *deviceConnection, uint32_t sessionId, uint32_t handle, uint32_t pAddrL2,
                                    uint32_t offsetPayload, uint32_t lenBulkMem, uint32_t *secureVirtualAdr)
 {
     TrustletSession *ts = getTrustletSession(sessionId);
@@ -455,6 +474,11 @@
         LOG_E("no session found with id=%d", sessionId);
         return MC_DRV_ERR_DAEMON_UNKNOWN_SESSION;
     }
+    /* The connection does not own this session ID! */
+    if(ts->deviceConnection != deviceConnection) {
+        LOG_E("no session found with id=%d", sessionId);
+        return MC_DRV_ERR_DAEMON_UNKNOWN_SESSION;
+    }
 
     // TODO-2012-09-06-haenellu: Think about not ignoring the error case, ClientLib does not allow this.
     ts->addBulkBuff(new CWsm((void *)offsetPayload, lenBulkMem, handle, (void *)pAddrL2));
@@ -493,7 +517,7 @@
 
 
 //------------------------------------------------------------------------------
-mcResult_t MobiCoreDevice::unmapBulk(uint32_t sessionId, uint32_t handle,
+mcResult_t MobiCoreDevice::unmapBulk(Connection *deviceConnection, uint32_t sessionId, uint32_t handle,
                                      uint32_t secureVirtualAdr, uint32_t lenBulkMem)
 {
     TrustletSession *ts = getTrustletSession(sessionId);
@@ -501,6 +525,11 @@
         LOG_E("no session found with id=%d", sessionId);
         return MC_DRV_ERR_DAEMON_UNKNOWN_SESSION;
     }
+    /* The connection does not own this session ID! */
+    if(ts->deviceConnection != deviceConnection) {
+        LOG_E("no session found with id=%d", sessionId);
+        return MC_DRV_ERR_DAEMON_UNKNOWN_SESSION;
+    }
 
     // Write MCP unmap command to buffer
     mcpMessage->cmdUnmap.cmdHeader.cmdId = MC_MCP_CMD_UNMAP;
@@ -643,4 +672,24 @@
     notifications.push(notification);
 }
 
+//------------------------------------------------------------------------------
+mcResult_t MobiCoreDevice::notify(Connection *deviceConnection, uint32_t sessionId)
+{
+    TrustletSession *ts = getTrustletSession(sessionId);
+    if (ts == NULL) {
+        LOG_E("no session found with id=%d", sessionId);
+        return MC_DRV_ERR_DAEMON_UNKNOWN_SESSION;
+    }
+
+    /* The connection does not own this trustlet session */
+    if (ts->deviceConnection != deviceConnection) {
+        LOG_E("no session found with id=%d", sessionId);
+        return MC_DRV_ERR_DAEMON_UNKNOWN_SESSION;
+    }
+
+    notify(sessionId);
+
+    return MC_DRV_OK;
+}
+
 /** @} */
diff --git a/daemon/Daemon/Device/Platforms/Generic/TrustZoneDevice.cpp b/daemon/Daemon/Device/Platforms/Generic/TrustZoneDevice.cpp
index 39bb006..838b39b 100644
--- a/daemon/Daemon/Device/Platforms/Generic/TrustZoneDevice.cpp
+++ b/daemon/Daemon/Device/Platforms/Generic/TrustZoneDevice.cpp
@@ -499,9 +499,9 @@
 }
 
 //------------------------------------------------------------------------------
-addr_t TrustZoneDevice::findWsmL2(uint32_t handle)
+addr_t TrustZoneDevice::findWsmL2(uint32_t handle, int fd)
 {
-    addr_t ret = pMcKMod->findWsmL2(handle);
+    addr_t ret = pMcKMod->findWsmL2(handle, fd);
     if (ret == NULL) {
         LOG_E("pMcKMod->findWsmL2 failed");
         return NULL;
@@ -511,9 +511,9 @@
 }
 
 //------------------------------------------------------------------------------
-bool TrustZoneDevice::findContiguousWsm(uint32_t handle, addr_t *phys, uint32_t *len)
+bool TrustZoneDevice::findContiguousWsm(uint32_t handle, int fd, addr_t *phys, uint32_t *len)
 {
-    if (pMcKMod->findContiguousWsm(handle, phys, len)) {
+    if (pMcKMod->findContiguousWsm(handle, fd, phys, len)) {
         LOG_E("pMcKMod->findContiguousWsm failed");
         return false;
     }
diff --git a/daemon/Daemon/Device/Platforms/Generic/TrustZoneDevice.h b/daemon/Daemon/Device/Platforms/Generic/TrustZoneDevice.h
index 478bc23..37646c7 100644
--- a/daemon/Daemon/Device/Platforms/Generic/TrustZoneDevice.h
+++ b/daemon/Daemon/Device/Platforms/Generic/TrustZoneDevice.h
@@ -115,9 +115,9 @@
 
     bool unlockWsmL2(uint32_t handle);
 
-    addr_t findWsmL2(uint32_t handle);
+    addr_t findWsmL2(uint32_t handle, int fd);
 
-    bool findContiguousWsm(uint32_t handle, addr_t *phys, uint32_t *len);
+    bool findContiguousWsm(uint32_t handle, int fd, addr_t *phys, uint32_t *len);
 
     /**
      * Cleanup all orphaned bulk buffers.
diff --git a/daemon/Daemon/Device/public/MobiCoreDevice.h b/daemon/Daemon/Device/public/MobiCoreDevice.h
index d95da4c..53c6c86 100644
--- a/daemon/Daemon/Device/public/MobiCoreDevice.h
+++ b/daemon/Daemon/Device/public/MobiCoreDevice.h
@@ -132,6 +132,7 @@
                            loadDataOpenSession_ptr         pLoadDataOpenSession,
                            uint32_t                        tciHandle,
                            uint32_t                        tciLen,
+                           uint32_t                        tciOffset,
                            mcDrvRspOpenSessionPayload_ptr  pRspOpenSessionPayload);
 
     TrustletSession *registerTrustletConnection(Connection *connection,
@@ -143,12 +144,14 @@
     // Do more checks
     mcResult_t closeSession(Connection *deviceConnection, uint32_t sessionId);
 
+    virtual mcResult_t notify(Connection *deviceConnection, uint32_t  sessionId);
     virtual void notify(uint32_t  sessionId) = 0;
 
-    mcResult_t mapBulk(uint32_t sessionId, uint32_t handle, uint32_t pAddrL2, uint32_t offsetPayload,
-                       uint32_t lenBulkMem, uint32_t *secureVirtualAdr);
+    mcResult_t mapBulk(Connection *deviceConnection, uint32_t sessionId, uint32_t handle, uint32_t pAddrL2,
+                        uint32_t offsetPayload, uint32_t lenBulkMem, uint32_t *secureVirtualAdr);
 
-    mcResult_t unmapBulk(uint32_t sessionId, uint32_t handle, uint32_t secureVirtualAdr, uint32_t lenBulkMem);
+    mcResult_t unmapBulk(Connection *deviceConnection, uint32_t sessionId, uint32_t handle,
+                        uint32_t secureVirtualAdr, uint32_t lenBulkMem);
 
     void start();
 
@@ -201,9 +204,9 @@
 
     virtual bool unlockWsmL2(uint32_t handle) = 0;
 
-    virtual addr_t findWsmL2(uint32_t handle) = 0;
+    virtual addr_t findWsmL2(uint32_t handle, int fd) = 0;
 
-    virtual bool findContiguousWsm(uint32_t handle, addr_t *phys, uint32_t *len) = 0;
+    virtual bool findContiguousWsm(uint32_t handle, int fd, addr_t *phys, uint32_t *len) = 0;
 
     /**
      * Cleanup all orphaned bulk buffers.
diff --git a/daemon/Daemon/MobiCoreDriverDaemon.cpp b/daemon/Daemon/MobiCoreDriverDaemon.cpp
index 5301575..cda7db0 100644
--- a/daemon/Daemon/MobiCoreDriverDaemon.cpp
+++ b/daemon/Daemon/MobiCoreDriverDaemon.cpp
@@ -164,6 +164,31 @@
     }
 }
 
+//------------------------------------------------------------------------------
+bool MobiCoreDriverDaemon::checkPermission(Connection *connection)
+{
+#ifdef REGISTRY_CHECK_PERMISSIONS
+    struct ucred cred;
+    if (!connection)
+        return true;
+
+    if (connection->getPeerCredentials(cred)) {
+        gid_t gid = getegid();
+        uid_t uid = geteuid();
+        LOG_I("Peer connection has pid = %u and uid = %u gid = %u", cred.pid, cred.uid, cred.gid);
+        LOG_I("Daemon has uid = %u gid = %u", cred.uid, cred.gid);
+        // If the daemon and the peer have the same uid or gid then we're good
+        if (gid == cred.gid || uid == cred.uid) {
+            return true;
+        }
+        return false;
+        
+    }
+    return false;
+#else
+    return true;
+#endif
+}
 
 //------------------------------------------------------------------------------
 MobiCoreDevice *MobiCoreDriverDaemon::getDevice(
@@ -255,6 +280,7 @@
                              &loadDataOpenSession,
                              pTciWsm->handle,
                              pTciWsm->len,
+                             0,
                              &(rspOpenSession.payload));
 
         // Unregister physical memory from kernel module.
@@ -429,6 +455,7 @@
                          &loadDataOpenSession,
                          cmdOpenSession.handle,
                          cmdOpenSession.len,
+                         cmdOpenSession.tci,
                          &rspOpenSession.payload);
 
     // Unregister physical memory from kernel module.
@@ -482,7 +509,7 @@
     }
 
     // Get service blob from registry
-    regObject_t *regObj = mcRegistryMemGetServiceBlob((uint8_t*)payload, len);
+    regObject_t *regObj = mcRegistryMemGetServiceBlob(cmdOpenTrustlet.spid, (uint8_t*)payload, len);
 
     // Free the payload object no matter what
     free(payload);
@@ -509,7 +536,7 @@
     loadDataOpenSession.baseAddr = pWsm->physAddr;
     loadDataOpenSession.offs = ((uint32_t) regObj->value) & 0xFFF;
     loadDataOpenSession.len = regObj->len;
-    loadDataOpenSession.tlHeader = (mclfHeader_ptr) regObj->value;
+    loadDataOpenSession.tlHeader = (mclfHeader_ptr) (regObj->value + regObj->tlStartOffset);
 
     mcDrvRspOpenSession_t rspOpenSession;
     mcResult_t ret = device->openSession(
@@ -517,6 +544,7 @@
                          &loadDataOpenSession,
                          cmdOpenTrustlet.handle,
                          cmdOpenTrustlet.len,
+                         cmdOpenTrustlet.tci,
                          &rspOpenSession.payload);
 
     // Unregister physical memory from kernel module.
@@ -640,11 +668,7 @@
         return;
     }
 
-    // REV axh: we cannot trust the clientLib to give us a valid
-    //          sessionId here. Thus we have to check that it belongs to
-    //          the clientLib's process.
-
-    device->notify(cmd.sessionId);
+    device->notify(connection, cmd.sessionId);
     // NOTE: for notifications there is no response at all
 }
 
@@ -667,7 +691,7 @@
     }
 
     uint32_t secureVirtualAdr = NULL;
-    uint32_t pAddrL2 = (uint32_t)device->findWsmL2(cmd.handle);
+    uint32_t pAddrL2 = (uint32_t)device->findWsmL2(cmd.handle, connection->socketDescriptor);
 
     if (pAddrL2 == 0) {
         LOG_E("Failed to resolve WSM with handle %u", cmd.handle);
@@ -676,7 +700,7 @@
     }
 
     // Map bulk memory to secure world
-    mcResult_t mcResult = device->mapBulk(cmd.sessionId, cmd.handle, pAddrL2,
+    mcResult_t mcResult = device->mapBulk(connection, cmd.sessionId, cmd.handle, pAddrL2,
                                           cmd.offsetPayload, cmd.lenBulkMem, &secureVirtualAdr);
 
     if (mcResult != MC_DRV_OK) {
@@ -703,7 +727,8 @@
     CHECK_DEVICE(device, connection);
 
     // Unmap bulk memory from secure world
-    uint32_t mcResult = device->unmapBulk(cmd.sessionId, cmd.handle, cmd.secureVirtualAdr, cmd.lenBulkMem);
+    uint32_t mcResult = device->unmapBulk(connection, cmd.sessionId, cmd.handle,
+                                        cmd.secureVirtualAdr, cmd.lenBulkMem);
 
     if (mcResult != MC_DRV_OK) {
         LOG_V("MCP UNMAP returned code %d", mcResult);
@@ -765,12 +790,17 @@
 {
     #define MAX_DATA_SIZE 512
     mcDrvResponseHeader_t rspRegistry = { responseId : MC_DRV_ERR_INVALID_OPERATION };
-    void *buf = malloc(MAX_DATA_SIZE); 
+    void *buf = alloca(MAX_DATA_SIZE); 
     uint32_t len = MAX_DATA_SIZE;
     mcSoAuthTokenCont_t auth;
     mcSpid_t spid;
     mcUuid_t uuid;
 
+    if (!checkPermission(connection)) {
+        connection->writeData(&rspRegistry, sizeof(rspRegistry));
+        return;
+    }
+
     switch(commandId) {
     case MC_DRV_REG_READ_AUTH_TOKEN:
         rspRegistry.responseId = mcRegistryReadAuthToken(&auth);
@@ -788,7 +818,9 @@
     case MC_DRV_REG_READ_TL_CONT:
         if (!getData(connection, &uuid, sizeof(uuid)))
             break;
-        rspRegistry.responseId = mcRegistryReadTrustletCon(&uuid, buf, &len);
+        if (!getData(connection, &spid, sizeof(spid)))
+            break;
+        rspRegistry.responseId = mcRegistryReadTrustletCon(&uuid, spid, buf, &len);
         break;
     default:
         break;
@@ -804,6 +836,12 @@
     mcDrvResponseHeader_t rspRegistry = { responseId : MC_DRV_ERR_INVALID_OPERATION };
     uint32_t soSize;
     void *so;
+
+    if (!checkPermission(connection)) {
+        connection->writeData(&rspRegistry, sizeof(rspRegistry));
+        return;
+    }
+
     // First read the SO data size
     if(!getData(connection, &soSize, sizeof(soSize))){
         LOG_E("Failed to read SO data size");
@@ -836,11 +874,14 @@
     }
     case MC_DRV_REG_WRITE_TL_CONT: {
         mcUuid_t uuid;
+        mcSpid_t spid;
         if (!getData(connection, &uuid, sizeof(uuid)))
             break;
+        if (!getData(connection, &spid, sizeof(spid)))
+            break;
         if (!getData(connection, so, soSize))
             break;
-        rspRegistry.responseId = mcRegistryStoreTrustletCon(&uuid, so, soSize);
+        rspRegistry.responseId = mcRegistryStoreTrustletCon(&uuid, spid, so, soSize);
         break;
     }
     case MC_DRV_REG_WRITE_SO_DATA: {
@@ -860,6 +901,12 @@
 void MobiCoreDriverDaemon::processRegistryDeleteData(uint32_t commandId, Connection *connection)
 {
     mcDrvResponseHeader_t rspRegistry = { responseId : MC_DRV_ERR_INVALID_OPERATION };
+    mcSpid_t spid;
+
+    if (!checkPermission(connection)) {
+        connection->writeData(&rspRegistry, sizeof(rspRegistry));
+        return;
+    }
 
     switch(commandId) {
     case MC_DRV_REG_DELETE_AUTH_TOKEN:
@@ -869,7 +916,6 @@
         rspRegistry.responseId = mcRegistryCleanupRoot();
         break;
     case MC_DRV_REG_DELETE_SP_CONT:
-        mcSpid_t spid;
         if (!getData(connection, &spid, sizeof(spid)))
             break;
         rspRegistry.responseId = mcRegistryCleanupSp(spid);
@@ -878,7 +924,9 @@
         mcUuid_t uuid;
         if (!getData(connection, &uuid, sizeof(uuid)))
             break;
-        rspRegistry.responseId = mcRegistryCleanupTrustlet(&uuid);
+        if (!getData(connection, &spid, sizeof(spid)))
+            break;
+        rspRegistry.responseId = mcRegistryCleanupTrustlet(&uuid, spid);
         break;
     default:
         break;
diff --git a/daemon/Daemon/MobiCoreDriverDaemon.h b/daemon/Daemon/MobiCoreDriverDaemon.h
index 3dfda56..497ac50 100644
--- a/daemon/Daemon/MobiCoreDriverDaemon.h
+++ b/daemon/Daemon/MobiCoreDriverDaemon.h
@@ -114,6 +114,8 @@
     /**< List of servers processing connections */
     Server *servers[MAX_SERVERS];
 
+    bool checkPermission(Connection *connection);
+
     size_t writeResult(
         Connection  *connection,
         mcResult_t  code
diff --git a/daemon/Daemon/Server/NetlinkServer.cpp b/daemon/Daemon/Server/NetlinkServer.cpp
index cdf80f5..8ed10dd 100644
--- a/daemon/Daemon/Server/NetlinkServer.cpp
+++ b/daemon/Daemon/Server/NetlinkServer.cpp
@@ -5,8 +5,8 @@
  * Connection server.
  *
  * Handles incoming socket connections from clients using the MobiCore driver.
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ */
+/* <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -115,7 +115,7 @@
         }
     } while (false);
 
-    LOG_ERRNO("Exiting NetlinkServer! Because it");
+    LOG_W("Could not open netlink socket. KernelAPI disabled");
 }
 
 //------------------------------------------------------------------------------
diff --git a/daemon/Daemon/Server/Server.cpp b/daemon/Daemon/Server/Server.cpp
index 085d0fd..ae08fe8 100644
--- a/daemon/Daemon/Server/Server.cpp
+++ b/daemon/Daemon/Server/Server.cpp
@@ -5,8 +5,8 @@
  * Connection server.
  *
  * Handles incoming socket connections from clients using the MobiCore driver.
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
+ */
+/* <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
diff --git a/daemon/Daemon/public/MobiCoreDriverCmd.h b/daemon/Daemon/public/MobiCoreDriverCmd.h
index da887c1..b9f73b6 100644
--- a/daemon/Daemon/public/MobiCoreDriverCmd.h
+++ b/daemon/Daemon/public/MobiCoreDriverCmd.h
@@ -131,6 +131,7 @@
 struct MC_DRV_CMD_OPEN_TRUSTLET_struct {
     uint32_t  commandId;
     uint32_t  deviceId;
+    mcSpid_t  spid;
     uint32_t  trustlet_len;
     uint32_t  tci;
     uint32_t  handle;
diff --git a/daemon/Kernel/Platforms/Generic/CMcKMod.cpp b/daemon/Kernel/Platforms/Generic/CMcKMod.cpp
index d517f67..2f130a4 100644
--- a/daemon/Kernel/Platforms/Generic/CMcKMod.cpp
+++ b/daemon/Kernel/Platforms/Generic/CMcKMod.cpp
@@ -439,10 +439,14 @@
 
 
 //------------------------------------------------------------------------------
-addr_t CMcKMod::findWsmL2(uint32_t handle)
+addr_t CMcKMod::findWsmL2(uint32_t handle, int fd)
 {
     int ret = 0;
-    uint32_t param = handle;
+    
+    struct mc_ioctl_resolv_wsm wsm;
+
+    wsm.handle = handle;
+    wsm.fd = fd;
 
     LOG_I(" Resolving the WSM l2 for handle=%u", handle);
 
@@ -451,22 +455,24 @@
         return NULL;
     }
 
-    ret = ioctl(fdKMod, MC_IO_RESOLVE_WSM, &param);
-    if (ret != 0 || param == 0) {
+    ret = ioctl(fdKMod, MC_IO_RESOLVE_WSM, &wsm);
+    if (ret != 0) {
         LOG_ERRNO("ioctl MC_IO_RESOLVE_WSM");
-        LOG_E("param %u, ret = %d", param, ret);
+        LOG_E("ret = %d", ret);
+        return 0;
     }
 
-    return (addr_t)param;
+    return (addr_t)wsm.phys;
 }
 
 //------------------------------------------------------------------------------
-mcResult_t CMcKMod::findContiguousWsm(uint32_t handle, addr_t *phys, uint32_t *len)
+mcResult_t CMcKMod::findContiguousWsm(uint32_t handle, int fd, addr_t *phys, uint32_t *len)
 {
     mcResult_t ret = MC_DRV_OK;
     struct mc_ioctl_resolv_cont_wsm wsm;
 
     wsm.handle = handle;
+    wsm.fd = fd;
 
     LOG_I(" Resolving the contiguous WSM l2 for handle=%u", handle);
 
diff --git a/daemon/Kernel/Platforms/Generic/CMcKMod.h b/daemon/Kernel/Platforms/Generic/CMcKMod.h
index b042add..c69e1e2 100644
--- a/daemon/Kernel/Platforms/Generic/CMcKMod.h
+++ b/daemon/Kernel/Platforms/Generic/CMcKMod.h
@@ -125,9 +125,9 @@
 
     mcResult_t cleanupWsmL2(void);
 
-    addr_t findWsmL2(uint32_t handle);
+    addr_t findWsmL2(uint32_t handle, int fd);
 
-    mcResult_t findContiguousWsm(uint32_t handle, addr_t *phys, uint32_t *len);
+    mcResult_t findContiguousWsm(uint32_t handle, int fd, addr_t *phys, uint32_t *len);
 
     mcResult_t setupLog(void);
 
diff --git a/daemon/Registry/PrivateRegistry.cpp b/daemon/Registry/PrivateRegistry.cpp
index 925f55a..75416be 100755
--- a/daemon/Registry/PrivateRegistry.cpp
+++ b/daemon/Registry/PrivateRegistry.cpp
@@ -60,8 +60,6 @@
 /** Maximum size of a shared object container in bytes. */
 #define MAX_SO_CONT_SIZE  (512)
 
-MC_CHECK_DATA_OBJECT_VERSION(MCLF, 2, 0);
-
 // Asserts expression at compile-time (to be used within a function body).
 #define ASSERT_STATIC(e) do { enum { assert_static__ = 1 / (e) }; } while (0)
 
@@ -177,9 +175,10 @@
 }
 
 //------------------------------------------------------------------------------
-static string getTlContFilePath(const mcUuid_t *uuid)
+static string getTlContFilePath(const mcUuid_t *uuid, const mcSpid_t spid)
 {
-    return getRegistryPath() + "/" + byteArrayToString(uuid, sizeof(*uuid)) + TL_CONT_FILE_EXT;
+    return getRegistryPath() + "/" + byteArrayToString(uuid, sizeof(*uuid))
+                + "." + uint32ToString(spid) + TL_CONT_FILE_EXT;
 }
 
 //------------------------------------------------------------------------------
@@ -203,7 +202,7 @@
 //------------------------------------------------------------------------------
 mcResult_t mcRegistryStoreAuthToken(void *so, uint32_t size)
 {
-    if (so == NULL) {
+    if (so == NULL || size > 3 * MAX_SO_CONT_SIZE) {
         LOG_E("mcRegistry store So.Soc failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
         return MC_DRV_ERR_INVALID_PARAMETER;
     }
@@ -268,7 +267,7 @@
 //------------------------------------------------------------------------------
 mcResult_t mcRegistryStoreRoot(void *so, uint32_t size)
 {
-    if (so == NULL) {
+    if (so == NULL || size > 3 * MAX_SO_CONT_SIZE) {
         LOG_E("mcRegistry store So.Root failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
         return MC_DRV_ERR_INVALID_PARAMETER;
     }
@@ -323,7 +322,7 @@
 //------------------------------------------------------------------------------
 mcResult_t mcRegistryStoreSp(mcSpid_t spid, void *so, uint32_t size)
 {
-    if ((spid == 0) || (so == NULL)) {
+    if ((spid == 0) || (so == NULL) || size > 3 * MAX_SO_CONT_SIZE) {
         LOG_E("mcRegistry store So.Sp(SpId) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
         return MC_DRV_ERR_INVALID_PARAMETER;
     }
@@ -375,14 +374,14 @@
 
 
 //------------------------------------------------------------------------------
-mcResult_t mcRegistryStoreTrustletCon(const mcUuid_t *uuid, void *so, uint32_t size)
+mcResult_t mcRegistryStoreTrustletCon(const mcUuid_t *uuid, const mcSpid_t spid, void *so, uint32_t size)
 {
-    if ((uuid == NULL) || (so == NULL)) {
+    if ((uuid == NULL) || (so == NULL) || size > 3 * MAX_SO_CONT_SIZE) {
         LOG_E("mcRegistry store So.TrustletCont(uuid) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
         return MC_DRV_ERR_INVALID_PARAMETER;
     }
 
-    const string &tlContFilePath = getTlContFilePath(uuid);
+    const string &tlContFilePath = getTlContFilePath(uuid, spid);
     LOG_I("store TLc: %s", tlContFilePath.c_str());
 
     FILE *fs = fopen(tlContFilePath.c_str(), "wb");
@@ -400,14 +399,14 @@
 
 
 //------------------------------------------------------------------------------
-mcResult_t mcRegistryReadTrustletCon(const mcUuid_t *uuid, void *so, uint32_t *size)
+mcResult_t mcRegistryReadTrustletCon(const mcUuid_t *uuid, const mcSpid_t spid, void *so, uint32_t *size)
 {
     if ((uuid == NULL) || (so == NULL)) {
         LOG_E("mcRegistry read So.TrustletCont(uuid) failed: %d", MC_DRV_ERR_INVALID_PARAMETER);
         return MC_DRV_ERR_INVALID_PARAMETER;
     }
     size_t readBytes;
-    const string &tlContFilePath = getTlContFilePath(uuid);
+    const string &tlContFilePath = getTlContFilePath(uuid, spid);
     LOG_I("read TLc: %s", tlContFilePath.c_str());
 
     FILE *fs = fopen(tlContFilePath.c_str(), "rb");
@@ -518,7 +517,7 @@
 
 
 //------------------------------------------------------------------------------
-mcResult_t mcRegistryCleanupTrustlet(const mcUuid_t *uuid)
+mcResult_t mcRegistryCleanupTrustlet(const mcUuid_t *uuid, const mcSpid_t spid)
 {
     DIR            *dp;
     struct dirent  *de;
@@ -552,7 +551,7 @@
         LOG_E("remove Tlb failed! errno: %d", e);
 //        return MC_DRV_ERR_UNKNOWN;     // a trustlet-binary must not be present ! (registered but not usable)
     }
-    string tlContFilePath = getTlContFilePath(uuid);
+    string tlContFilePath = getTlContFilePath(uuid, spid);
     LOG_I("delete Tlc: %s", tlContFilePath.c_str());
     if (0 != (e = remove(tlContFilePath.c_str()))) {
         LOG_E("remove Tlc failed! errno: %d", e);
@@ -584,7 +583,7 @@
     }
     for (i = 0; (i < MC_CONT_CHILDREN_COUNT) && (ret == MC_DRV_OK); i++) {
         if (0 != strncmp((const char *) & (data.cont.children[i]), (const char *)&MC_UUID_FREE, sizeof(mcUuid_t))) {
-            ret = mcRegistryCleanupTrustlet(&(data.cont.children[i]));
+            ret = mcRegistryCleanupTrustlet(&(data.cont.children[i]), spid);
         }
     }
     if (MC_DRV_OK != ret) {
@@ -654,7 +653,7 @@
 }
 
 //------------------------------------------------------------------------------
-regObject_t *mcRegistryMemGetServiceBlob(void *trustlet, uint32_t tlSize)
+regObject_t *mcRegistryMemGetServiceBlob(mcSpid_t spid, void *trustlet, uint32_t tlSize)
 {
     regObject_t *regobj = NULL;
 
@@ -724,9 +723,7 @@
         memcpy(p, trustlet, tlSize);
         p += tlSize;
 
-        // Goto end of allocated space and fill in tl container, sp container,
-        // and root container from back to front. Final registry object value
-        // looks like this:
+        // Final registry object value looks like this:
         //
         //    +---------------+---------------------------+-----------+---------+---------+
         //    | Blob Len Info | TL-Header TL-Code TL-Data | Root Cont | SP Cont | TL Cont |
@@ -737,33 +734,9 @@
 
         // start at the end of the trustlet blob
         mcResult_t ret;
-        void *soTltCont = malloc(MAX_SO_CONT_SIZE);
         do {
             uint32_t soTltContSize = MAX_SO_CONT_SIZE;
             uint32_t len;
-            mcTltContCommon_t *tltCont;
-            // We don't know exactly where to place the Trustlet container because it can
-            // have variable size, so use a separate buffer and copy it to the main blob
-            // at the end
-            if (MC_DRV_OK != (ret = mcRegistryReadTrustletCon(&pHeader->uuid, soTltCont, &soTltContSize))) {
-                break;
-            }
-            lenInfo->tlContBlobSize = soTltContSize;
-            LOG_I("Trustlet container %u bytes loaded", soTltContSize);
-            // Depending on the trustlet container size we decide which structure to use
-            // Unfortunate design but it should have to do for now
-            if (soTltContSize == sizeof(mcSoTltCont_2_0_t)) {
-                LOG_I("Using 2.0 trustlet container");
-                tltCont = &(((mcSoTltCont_2_0_t*)soTltCont)->cont.common);
-            }
-            else if (soTltContSize == sizeof(mcSoTltCont_2_1_t)) {
-                LOG_I("Using 2.1 trustlet container");
-                tltCont = &(((mcSoTltCont_2_1_t*)soTltCont)->cont.common);
-            }
-            else {
-                LOG_E("Trustlet container has unknown size");
-                break;
-            }
             
             // Fill in root container.
             len = sizeof(mcSoRootCont_t);
@@ -774,7 +747,6 @@
             p += len;
 
             // Fill in SP container.
-            mcSpid_t spid = tltCont->parent;
             len = sizeof(mcSoSpCont_t);
             if (MC_DRV_OK != (ret = mcRegistryReadSp(spid, p, &len))) {
                 break;
@@ -782,12 +754,29 @@
             lenInfo->spContBlobSize = len;
             p += len;
             
-            // Fill in TL container.
-            memcpy(p, soTltCont, soTltContSize);
+            // Fill in TLT Container
+            // We know exactly how much space is left in the buffer
+            soTltContSize = regObjValueSize - tlSize + sizeof(mcBlobLenInfo_t)
+                - lenInfo->spContBlobSize - lenInfo->rootContBlobSize;
+            if (MC_DRV_OK != (ret = mcRegistryReadTrustletCon(&pHeader->uuid, spid, p, &soTltContSize))) {
+                break;
+            }
+            lenInfo->tlContBlobSize = soTltContSize;
+            LOG_I("Trustlet container %u bytes loaded", soTltContSize);
+            // Depending on the trustlet container size we decide which structure to use
+            // Unfortunate design but it should have to do for now
+            if (soTltContSize == sizeof(mcSoTltCont_2_0_t)) {
+                LOG_I("Using 2.0 trustlet container");
+            }
+            else if (soTltContSize == sizeof(mcSoTltCont_2_1_t)) {
+                LOG_I("Using 2.1 trustlet container");
+            }
+            else {
+                LOG_E("Trustlet container has unknown size");
+                break;
+            }
         } while (false);
 
-        free(soTltCont);
-
         if (MC_DRV_OK != ret) {
             LOG_E("mcRegistryGetServiceBlob() failed: Error code: %d", ret);
             free(regobj);
@@ -836,7 +825,7 @@
         goto error;
     }
 
-    regobj = mcRegistryMemGetServiceBlob(buffer, sb.st_size);
+    regobj = mcRegistryMemGetServiceBlob(0, buffer, sb.st_size);
 
     // We don't actually care if either of them fails but should still print warnings
     if (munmap(buffer, sb.st_size)) {
diff --git a/daemon/Registry/PrivateRegistry.h b/daemon/Registry/PrivateRegistry.h
index 6319af7..59236cf 100755
--- a/daemon/Registry/PrivateRegistry.h
+++ b/daemon/Registry/PrivateRegistry.h
@@ -112,23 +112,26 @@
     /** Stores a trustlet container secure object in the registry.
      * @param uuid Trustlet UUID.
      * @param so Trustlet container secure object.
-     * @param size Trustlet container secure object size.
+     * @param size Trustlet container secure object size
      * @return MC_DRV_OK if successful, otherwise error code.
      */
-    mcResult_t mcRegistryStoreTrustletCon(const mcUuid_t *uuid, void *so, uint32_t size);
+    mcResult_t mcRegistryStoreTrustletCon(const mcUuid_t *uuid, const mcSpid_t spid, void *so, uint32_t size);
 
     /** Reads a trustlet container secure object from the registry.
      * @param uuid Trustlet UUID.
+     * @param spid SPID of the trustlet container
      * @param[out] so Trustlet container secure object.
+     * @param[out] size Trustlet container secure object size
      * @return MC_DRV_OK if successful, otherwise error code.
      */
-    mcResult_t mcRegistryReadTrustletCon(const mcUuid_t *uuid, void *so, uint32_t *size);
+    mcResult_t mcRegistryReadTrustletCon(const mcUuid_t *uuid, const mcSpid_t spid, void *so, uint32_t *size);
 
     /** Deletes a trustlet container secure object and all of its associated data.
      * @param uuid Trustlet UUID.
+     * @param spid Service provider ID
      * @return MC_DRV_OK if successful, otherwise error code.
      */
-    mcResult_t mcRegistryCleanupTrustlet(const mcUuid_t *uuid);
+    mcResult_t mcRegistryCleanupTrustlet(const mcUuid_t *uuid, const mcSpid_t spid);
 
     /** Stores a data container secure object in the registry.
      * @param so Data container secure object.
@@ -159,13 +162,14 @@
     mcResult_t mcRegistryCleanupRoot(void);
 
     /** Returns a registry object for a given service from memory
+     * @param spid Service provider ID(ignored for System TLs)
      * @param trustlet buffer with trustlet binary
      * @param tlSize buffer size
      * @return Registry object.
      * @note It is the responsibility of the caller to free the registry object
      * allocated by this function.
      */
-    regObject_t *mcRegistryMemGetServiceBlob(void *trustlet, uint32_t tlSize);
+    regObject_t *mcRegistryMemGetServiceBlob(mcSpid_t spid, void *trustlet, uint32_t tlSize);
 
     /** Returns a registry object for a given service.
      * @param uuid service UUID
diff --git a/daemon/Registry/Public/MobiCoreRegistry.h b/daemon/Registry/Public/MobiCoreRegistry.h
index 56baf33..e231702 100644
--- a/daemon/Registry/Public/MobiCoreRegistry.h
+++ b/daemon/Registry/Public/MobiCoreRegistry.h
@@ -104,28 +104,23 @@
      * @param size Trustlet container secure object size
      * @return MC_DRV_OK if successful, otherwise error code.
      */
-    mcResult_t mcRegistryStoreTrustletCon(const mcUuid_t *uuid, void *so, uint32_t size);
+    mcResult_t mcRegistryStoreTrustletCon(const mcUuid_t *uuid, const mcSpid_t spid, void *so, uint32_t size);
 
     /** Reads a trustlet container secure object from the registry.
      * @param uuid Trustlet UUID.
+     * @param spid SPID of the trustlet container
      * @param[out] so Trustlet container secure object.
      * @param[out] size Trustlet container secure object size
      * @return MC_DRV_OK if successful, otherwise error code.
      */
-    mcResult_t mcRegistryReadTrustletCon(const mcUuid_t *uuid, void *so, uint32_t *size);
+    mcResult_t mcRegistryReadTrustletCon(const mcUuid_t *uuid, const mcSpid_t spid, void *so, uint32_t *size);
 
     /** Deletes a trustlet container secure object and all of its associated data.
      * @param uuid Trustlet UUID.
+     * @param spid Service provider ID
      * @return MC_DRV_OK if successful, otherwise error code.
      */
-    mcResult_t mcRegistryCleanupTrustlet(const mcUuid_t *uuid);
-
-    /** Stores a data container secure object in the registry.
-     * @param so Data container secure object.
-     * @param size Data container secure object size
-     * @return MC_DRV_OK if successful, otherwise error code.
-     */
-    mcResult_t mcRegistryStoreData(void *so, uint32_t size);
+    mcResult_t mcRegistryCleanupTrustlet(const mcUuid_t *uuid, const mcSpid_t spid);
 
     /** Deletes the root container and all of its associated service provider
      * containers.
diff --git a/daemon/Registry/Registry.cpp b/daemon/Registry/Registry.cpp
index ff5f517..f37ec69 100755
--- a/daemon/Registry/Registry.cpp
+++ b/daemon/Registry/Registry.cpp
@@ -52,7 +52,7 @@
 
 #include "Connection.h"
 
-#define DAEMON_TIMEOUT 30
+#define DAEMON_TIMEOUT 30000
 
 using namespace std;
 
@@ -258,12 +258,13 @@
 }
 
 //------------------------------------------------------------------------------
-mcResult_t mcRegistryStoreTrustletCon(const mcUuid_t *uuid, void *so, uint32_t size)
+mcResult_t mcRegistryStoreTrustletCon(const mcUuid_t *uuid, mcSpid_t spid, void *so, uint32_t size)
 {
     typedef struct {
         uint32_t commandId;
         uint32_t soSize;
         mcUuid_t uuid;
+        mcSpid_t spid;
         uint8_t so;
     } storeCmd;
 
@@ -272,6 +273,7 @@
     
     cmd->commandId = MC_DRV_REG_WRITE_TL_CONT;
     cmd->soSize = size;
+    cmd->spid = spid;
     memcpy(&cmd->uuid, uuid, sizeof(mcUuid_t));
     memcpy(&cmd->so, so, size);
 
@@ -282,15 +284,17 @@
 
 
 //------------------------------------------------------------------------------
-mcResult_t mcRegistryReadTrustletCon(const mcUuid_t *uuid, void *so, uint32_t *size)
+mcResult_t mcRegistryReadTrustletCon(const mcUuid_t *uuid, mcSpid_t spid, void *so, uint32_t *size)
 {
     struct {
         uint32_t commandId;
         mcUuid_t uuid;
+        mcSpid_t spid;
     } cmd;
     mcResult_t ret;
     uint32_t rsize;
     cmd.commandId = MC_DRV_REG_READ_TL_CONT;
+    cmd.spid = spid;
     memcpy(&cmd.uuid, uuid, sizeof(mcUuid_t));
 
     rsize = *size;
@@ -300,14 +304,16 @@
 }
 
 //------------------------------------------------------------------------------
-mcResult_t mcRegistryCleanupTrustlet(const mcUuid_t *uuid)
+mcResult_t mcRegistryCleanupTrustlet(const mcUuid_t *uuid, const mcSpid_t spid)
 {
     struct {
         uint32_t commandId;
         mcUuid_t uuid;
+        mcSpid_t spid;
     } cmd;
 
     cmd.commandId = MC_DRV_REG_DELETE_TL_CONT;
+    cmd.spid = spid;
     memcpy(&cmd.uuid, uuid, sizeof(mcUuid_t));
 
     return writeBlobData(&cmd, sizeof(cmd));
diff --git a/daemon/buildTag.h b/daemon/buildTag.h
index 92f2123..7c4d581 100644
--- a/daemon/buildTag.h
+++ b/daemon/buildTag.h
@@ -1,5 +1,5 @@
-/** Build tag created during build by ./Out/_build/_src/Scripts/trunk/00025766/Out/setBuildTag.sh.
- * <-- Copyright Giesecke & Devrient GmbH 2012-2012 -->
+/** Build tag created during build by ./Out/_build/_src/Scripts/trunk/00029519/Out/setBuildTag.sh.
+ * <-- Copyright Trustonic Limited 2013 -->
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,4 +26,4 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #define MOBICORE_COMPONENT_BUILD_TAG \
-		"*** GC_MSM8960_Release_V014 ###"
+		"*** GC_MSM8960_Release_V016 ###"
diff --git a/include/Public/mc_linux.h b/include/Public/mc_linux.h
index 62b2b73..9c49aef 100644
--- a/include/Public/mc_linux.h
+++ b/include/Public/mc_linux.h
@@ -1,14 +1,8 @@
-/** @addtogroup MCD_MCDIMPL_KMOD_API Mobicore Driver Module API
- * @ingroup  MCD_MCDIMPL_KMOD
- * @{
- * Interface to Mobicore Driver Kernel Module.
- * @file
- *
- * <h2>Introduction</h2>
+/*
  * The MobiCore Driver Kernel Module is a Linux device driver, which represents
  * the command proxy on the lowest layer to the secure world (Swd). Additional
  * services like memory allocation via mmap and generation of a L2 tables for
- * given virtual memory are also supported. IRQ functionallity receives
+ * given virtual memory are also supported. IRQ functionality receives
  * information from the SWd in the non secure world (NWd).
  * As customary the driver is handled as linux device driver with "open",
  * "close" and "ioctl" commands. Access to the driver is possible after the
@@ -16,16 +10,8 @@
  * The MobiCore Driver Kernel Module must be installed via
  * "insmod mcDrvModule.ko".
  *
- *
- * <h2>Version history</h2>
- * <table class="customtab">
- * <tr><td width="100px"><b>Date</b></td><td width="80px"><b>Version</b></td>
- * <td><b>Changes</b></td></tr>
- * <tr><td>2010-05-25</td><td>0.1</td><td>Initial Release</td></tr>
- * </table>
- *
- * <!-- Copyright Giesecke & Devrient GmbH 2010-2012 -->
- * <!-- Copyright Trustonic Limited 2013 -->
+ * <-- Copyright Giesecke & Devrient GmbH 2010-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -60,54 +46,50 @@
 #define MC_ADMIN_DEVNODE	"mobicore"
 #define MC_USER_DEVNODE		"mobicore-user"
 
-/**
+/*
  * Data exchange structure of the MC_DRV_MODULE_INIT ioctl command.
  * INIT request data to SWD
  */
 struct mc_ioctl_init {
-	/** notification buffer start/length [16:16] [start, length] */
+	/* notification buffer start/length [16:16] [start, length] */
 	uint32_t  nq_offset;
-	/** length of notification queue */
+	/* length of notification queue */
 	uint32_t  nq_length;
-	/** mcp buffer start/length [16:16] [start, length] */
+	/* mcp buffer start/length [16:16] [start, length] */
 	uint32_t  mcp_offset;
-	/** length of mcp buffer */
+	/* length of mcp buffer */
 	uint32_t  mcp_length;
 };
 
-
-/**
+/*
  * Data exchange structure of the MC_DRV_MODULE_INFO ioctl command.
  * INFO request data to the SWD
  */
 struct mc_ioctl_info {
-	uint32_t  ext_info_id; /**< extended info ID */
-	uint32_t  state; /**< state */
-	uint32_t  ext_info; /**< extended info */
+	uint32_t  ext_info_id;	/* extended info ID */
+	uint32_t  state;	/* state */
+	uint32_t  ext_info;	/* extended info */
 };
 
-/**
- * Mmap allocates and maps contiguous memory into a process.
- * We use the third parameter, void *offset, to distinguish between some cases
- * offset = MC_DRV_KMOD_MMAP_WSM	usual operation, pages are registered in
- *					device structure and freed later.
- * offset = MC_DRV_KMOD_MMAP_MCI	get Instance of MCI, allocates or mmaps
- *					the MCI to daemon
+/*
+ * Data exchange structure of the MC_IO_MAP_WSM, MC_IO_MAP_MCI, and
+ *				  MC_IO_MAP_PWSM commands.
  *
- * In mmap(), the offset specifies which of several device I/O pages is
- *  requested. Linux only transfers the page number, i.e. the upper 20 bits to
- *  kernel module. Therefore we define our special offsets as multiples of page
- *  size.
+ * Allocate a contiguous memory buffer for a process.
+ * The physical address can be used as for later calls to mmap.
+ * The handle can be used to communicate about this buffer to the Daemon.
+ * For MC_IO_MAP_MCI command, the reused field indicates that MCI was set up
+ * already. I.e. Daemon was restarted.
  */
 struct mc_ioctl_map {
-	size_t    len; /**<  Buffer length */
-	uint32_t  handle; /**< WSM handle */
-	unsigned long  addr; /**< Virtual address */
-	unsigned long  phys_addr; /**< physical address of WSM (or NULL) */
-	bool      reused; /**< if WSM memory was reused, or new allocated */
+	size_t	      len;	/* Buffer length */
+	uint32_t      handle;	/* WSM handle */
+	unsigned long addr;	/* Virtual address */
+	unsigned long phys_addr;/* physical address of WSM (or NULL) */
+	bool	      reused;	/* if WSM memory was reused, or new allocated */
 };
 
-/**
+/*
  * Data exchange structure of the MC_IO_REG_WSM command.
  *
  * Allocates a physical L2 table and maps the buffer into this page.
@@ -116,42 +98,53 @@
  * will be modified to the used values.
  */
 struct mc_ioctl_reg_wsm {
-	uint32_t  buffer; /**< base address of the virtual address  */
-	uint32_t  len; /**< size of the virtual address space */
-	uint32_t  pid; /**< process id */
-	uint32_t  handle; /**< driver handle for locked memory */
-	uint32_t  table_phys; /**< physical address of the L2 table */
+	uint32_t buffer;	/* base address of the virtual address  */
+	uint32_t len;		/* size of the virtual address space */
+	uint32_t pid;		/* process id */
+	uint32_t handle;	/* driver handle for locked memory */
+	uint32_t table_phys;	/* physical address of the L2 table */
 };
 
 
-/**
+/*
  * Data exchange structure of the MC_DRV_MODULE_FC_EXECUTE ioctl command.
  * internal, unsupported
  */
 struct mc_ioctl_execute {
-	/**< base address of mobicore binary */
-	uint32_t  phys_start_addr;
-	/**< length of DDR area */
-	uint32_t  length;
+	/* base address of mobicore binary */
+	uint32_t phys_start_addr;
+	/* length of DDR area */
+	uint32_t length;
 };
 
-/**
+/*
  * Data exchange structure of the MC_IO_RESOLVE_CONT_WSM ioctl command.
  */
 struct mc_ioctl_resolv_cont_wsm {
-	/**< driver handle for buffer */
-	uint32_t  handle;
-	/**< base address of memory */
-	uint32_t  phys;
-	/**< length memory */
-	uint32_t  length;
+	/* driver handle for buffer */
+	uint32_t handle;
+	/* base address of memory */
+	uint32_t phys;
+	/* length memory */
+	uint32_t length;
+	/* fd to owner of the buffer */
+	int32_t fd;
+};
+
+/*
+ * Data exchange structure of the MC_IO_RESOLVE_WSM ioctl command.
+ */
+struct mc_ioctl_resolv_wsm {
+	/* driver handle for buffer */
+	uint32_t handle;
+	/* fd to owner of the buffer */
+	int32_t fd;
+	/* base address of memory */
+	uint32_t phys;
 };
 
 
-/* @defgroup Mobicore_Driver_Kernel_Module_Interface IOCTL */
-
-
-/**
+/*
  * defines for the ioctl mobicore driver module function call from user space.
  */
 /* MobiCore IOCTL magic number */
@@ -160,29 +153,29 @@
 #define MC_IO_INIT		_IOWR(MC_IOC_MAGIC, 0, struct mc_ioctl_init)
 #define MC_IO_INFO		_IOWR(MC_IOC_MAGIC, 1, struct mc_ioctl_info)
 #define MC_IO_VERSION		_IOR(MC_IOC_MAGIC, 2, uint32_t)
-/**
+/*
  * ioctl parameter to send the YIELD command to the SWD.
  * Only possible in Privileged Mode.
  * ioctl(fd, MC_DRV_MODULE_YIELD)
  */
 #define MC_IO_YIELD		_IO(MC_IOC_MAGIC, 3)
-/**
+/*
  * ioctl parameter to send the NSIQ signal to the SWD.
  * Only possible in Privileged Mode
  * ioctl(fd, MC_DRV_MODULE_NSIQ)
  */
 #define MC_IO_NSIQ		_IO(MC_IOC_MAGIC, 4)
-/**
+/*
  * Free's memory which is formerly allocated by the driver's mmap
  * command. The parameter must be this mmaped address.
  * The internal instance data regarding to this address are deleted as
  * well as each according memory page and its appropriated reserved bit
  * is cleared (ClearPageReserved).
- * Usage: ioctl(fd, MC_DRV_MODULE_FREE, &address) with address beeing of
+ * Usage: ioctl(fd, MC_DRV_MODULE_FREE, &address) with address being of
  * type long address
  */
 #define MC_IO_FREE		_IO(MC_IOC_MAGIC, 5)
-/**
+/*
  * Creates a L2 Table of the given base address and the size of the
  * data.
  * Parameter: mc_ioctl_app_reg_wsm_l2_params
@@ -193,8 +186,8 @@
 #define MC_IO_UNLOCK_WSM	_IO(MC_IOC_MAGIC, 9)
 #define MC_IO_EXECUTE		_IOWR(MC_IOC_MAGIC, 10, struct mc_ioctl_execute)
 
-/**
- * Mmap allocates and maps contiguous memory into a process.
+/*
+ * Allocate contiguous memory for a process for later mapping with mmap.
  * MC_DRV_KMOD_MMAP_WSM	usual operation, pages are registered in
  *					device structure and freed later.
  * MC_DRV_KMOD_MMAP_MCI	get Instance of MCI, allocates or mmaps
@@ -206,23 +199,29 @@
 #define MC_IO_MAP_MCI		_IOWR(MC_IOC_MAGIC, 12, struct mc_ioctl_map)
 #define MC_IO_MAP_PWSM		_IOWR(MC_IOC_MAGIC, 13, struct mc_ioctl_map)
 
-/**
+/*
  * Clean orphaned WSM buffers. Only available to the daemon and should
  * only be carried out if the TLC crashes or otherwise calls exit() in
  * an unexpected manner.
- * The clean is needed toghether with the lock/unlock mechanism so the daemon
- * has clear control of the mapped buffers so it can close a truslet before
- * release all the WSM buffers, otherwise the trustlet would be able to write
- * to possibly kernel memory areas */
+ * The clean is needed together with the lock/unlock mechanism so the daemon
+ * has clear control of the mapped buffers so it can close a Trustlet before
+ * release all the WSM buffers, otherwise the Trustlet would be able to write
+ * to possibly kernel memory areas
+ */
 #define MC_IO_CLEAN_WSM		_IO(MC_IOC_MAGIC, 14)
 
-/** Get L2 phys address of a buffer handle allocated to the user. Only
- * available to the daemon */
-#define MC_IO_RESOLVE_WSM	_IOWR(MC_IOC_MAGIC, 15, uint32_t)
+/*
+ * Get L2 phys address of a buffer handle allocated to the user.
+ * Only available to the daemon.
+ */
+#define MC_IO_RESOLVE_WSM	_IOWR(MC_IOC_MAGIC, 15, \
+					struct mc_ioctl_resolv_wsm)
 
-/** Get the phys address & len of a allocated contiguous buffer. Only available
- * to the daemon */
-#define MC_IO_RESOLVE_CONT_WSM	_IOWR(MC_IOC_MAGIC, 16, struct mc_ioctl_execute)
+/*
+ * Get the phys address & length of a allocated contiguous buffer.
+ * Only available to the daemon */
+#define MC_IO_RESOLVE_CONT_WSM	_IOWR(MC_IOC_MAGIC, 16, \
+					struct mc_ioctl_resolv_cont_wsm)
 
 /*
  * Setup the mem traces when called.
@@ -230,4 +229,3 @@
 #define MC_IO_LOG_SETUP		_IO(MC_IOC_MAGIC, 17)
 
 #endif /* _MC_LINUX_H_ */
-/** @} */
diff --git a/include/Public/version.h b/include/Public/version.h
index 1d5528c..591ca3d 100644
--- a/include/Public/version.h
+++ b/include/Public/version.h
@@ -1,7 +1,6 @@
-/** @addtogroup MCD_MCDIMPL_KMOD
- * @{
- * <!-- Copyright Giesecke & Devrient GmbH 2010-2012 -->
- * <!-- Copyright Trustonic Limited 2013 -->
+/*
+ * <-- Copyright Giesecke & Devrient GmbH 2010-2012 -->
+ * <-- Copyright Trustonic Limited 2013 -->
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
diff --git a/rootpa/Code/Android/app/Android.mk b/rootpa/Code/Android/app/Android.mk
index 080b433..438c6f0 100755
--- a/rootpa/Code/Android/app/Android.mk
+++ b/rootpa/Code/Android/app/Android.mk
@@ -7,10 +7,11 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_STATIC_JAVA_LIBRARIES := rootpa_interface
-LOCAL_JNI_SHARED_LIBRARIES := commonpawrapper
+LOCAL_JNI_SHARED_LIBRARIES := libcommonpawrapper
 
 LOCAL_PACKAGE_NAME := RootPA
 LOCAL_MODULE_TAGS := optional
+LOCAL_CERTIFICATE := platform
 
 include $(BUILD_PACKAGE)
 
diff --git a/rootpa/Code/Android/app/AndroidManifest.xml b/rootpa/Code/Android/app/AndroidManifest.xml
index 43abb7e..547fe8a 100755
--- a/rootpa/Code/Android/app/AndroidManifest.xml
+++ b/rootpa/Code/Android/app/AndroidManifest.xml
@@ -3,13 +3,16 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 
           package="com.gd.mobicore.pa"
           android:versionCode="1" 
-          android:versionName="1.0" >
+          android:versionName="1.0" 
+          android:sharedUserId="android.uid.system" >
 
-  <uses-sdk android:minSdkVersion="8"
-           android:targetSdkVersion="16" />
+  <uses-sdk android:minSdkVersion="14"
+           android:targetSdkVersion="17" />
 
   <uses-permission android:name="android.permission.INTERNET"/>
+  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />  
   <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     
   <permission android:name="com.gd.mobicore.pa.permission.OEM_PERMISSION"
         android:label="remove installed secure services"
diff --git a/rootpa/Code/Android/app/ant.properties b/rootpa/Code/Android/app/ant.properties
index d982513..452d2d4 100755
--- a/rootpa/Code/Android/app/ant.properties
+++ b/rootpa/Code/Android/app/ant.properties
@@ -1,2 +1,7 @@
 out.dir=out
 java.compilerargs="-Xlint:unchecked"
+
+debug.key.store=../../../Build/google_certificate.keystore
+debug.key.alias=platform
+debug.key.store.password=android
+debug.key.alias.password=android
\ No newline at end of file
diff --git a/rootpa/Code/Android/app/jni/Common/Android.mk b/rootpa/Code/Android/app/jni/Common/Android.mk
index 4c3295d..7fbf94d 100755
--- a/rootpa/Code/Android/app/jni/Common/Android.mk
+++ b/rootpa/Code/Android/app/jni/Common/Android.mk
@@ -77,13 +77,6 @@
     LOCAL_MODULE    := provisioningagent
 endif
 
-#LOCAL_LDLIBS += -lMcRegistry
-
-#LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
-#LOCAL_SHARED_LIBRARIES  += libMcClient
-#LOCAL_SHARED_LIBRARIES  += libMcRegistry
-#LOCAL_SHARED_LIBRARIES  += liblog
-
 LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_STATIC_LIBRARY)
diff --git a/rootpa/Code/Android/app/jni/CommonPAWrapper/Android.mk b/rootpa/Code/Android/app/jni/CommonPAWrapper/Android.mk
index 00f23da..1bfefef 100755
--- a/rootpa/Code/Android/app/jni/CommonPAWrapper/Android.mk
+++ b/rootpa/Code/Android/app/jni/CommonPAWrapper/Android.mk
@@ -57,7 +57,7 @@
 LOCAL_C_INCLUDES +=  $(MOBICORE_DIR_INC)/TlCm
 LOCAL_C_INCLUDES +=  $(LOCAL_PATH)/../../../../Common/include
 
-LOCAL_MODULE    := commonpawrapper
+LOCAL_MODULE    := libcommonpawrapper
 LOCAL_MODULE_TAGS := optional
 
 ifeq ($(ROOTPA_MODULE_TEST), 1)
@@ -77,9 +77,8 @@
 LOCAL_SHARED_LIBRARIES += libssl
 LOCAL_SHARED_LIBRARIES += libcrypto
 LOCAL_SHARED_LIBRARIES += libcurl
-LOCAL_SHARED_LIBRARIES += libicuuc
 LOCAL_STATIC_LIBRARIES += libxml2
-
+LOCAL_SHARED_LIBRARIES += libicuuc
 
 include $(BUILD_SHARED_LIBRARY)
 
diff --git a/rootpa/Code/Android/app/jni/CommonPAWrapper/com_gd_mobicore_pa_jni_CommonPAWrapper.h b/rootpa/Code/Android/app/jni/CommonPAWrapper/com_gd_mobicore_pa_jni_CommonPAWrapper.h
index 16a65ea..66a9e0a 100755
--- a/rootpa/Code/Android/app/jni/CommonPAWrapper/com_gd_mobicore_pa_jni_CommonPAWrapper.h
+++ b/rootpa/Code/Android/app/jni/CommonPAWrapper/com_gd_mobicore_pa_jni_CommonPAWrapper.h
@@ -28,6 +28,7 @@
 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
 OF THE POSSIBILITY OF SUCH DAMAGE.
 */
+
 /* DO NOT EDIT THIS FILE - it is machine generated */
 #include <jni.h>
 /* Header for class com_gd_mobicore_pa_jni_CommonPAWrapper */
@@ -144,11 +145,19 @@
 /*
  * Class:     com_gd_mobicore_pa_jni_CommonPAWrapper
  * Method:    unregisterRootContainer
- * Signature: ()I
+ * Signature: ([B)I
  */
 JNIEXPORT jint JNICALL Java_com_gd_mobicore_pa_jni_CommonPAWrapper_unregisterRootContainer
   (JNIEnv *, jobject, jbyteArray);
 
+/*
+ * Class:     com_gd_mobicore_pa_jni_CommonPAWrapper
+ * Method:    setEnvironmentVariable
+ * Signature: ([B[B)I
+ */
+JNIEXPORT void JNICALL Java_com_gd_mobicore_pa_jni_CommonPAWrapper_setEnvironmentVariable
+  (JNIEnv *, jobject, jbyteArray, jbyteArray);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/rootpa/Code/Android/app/jni/CommonPAWrapper/commonwrapper.cpp b/rootpa/Code/Android/app/jni/CommonPAWrapper/commonwrapper.cpp
index 3f32b05..8d59dad 100755
--- a/rootpa/Code/Android/app/jni/CommonPAWrapper/commonwrapper.cpp
+++ b/rootpa/Code/Android/app/jni/CommonPAWrapper/commonwrapper.cpp
@@ -40,6 +40,7 @@
 #include "provisioningagent.h"
 
 #define SPID_DEVELOPER_SP 0
+#define CERT_PATH "/system/etc/security/cacerts"
 
 JavaVM* jvmP_ = NULL;
 const jint VERSION=JNI_VERSION_1_2;
@@ -119,7 +120,7 @@
     }
     delete commands;
     delete responses;
-    LOGD("<<Java_com_gd_mobicore_pa_jni_CommonPAWrapper_executeCmpCommands\n");
+    LOGD("<<Java_com_gd_mobicore_pa_jni_CommonPAWrapper_executeCmpCommands %d\n", ret);
 
     return ret;
 }
@@ -152,29 +153,27 @@
         ret=jniHelp.setVersion((char*) VERSION_FIELD_TAG, tag);
         if(ROOTPA_OK == ret)
         {
-            if(1==tag)
+            ret=jniHelp.setProductId((char*) version.productId);
+            if(ret != ROOTPA_OK) return ret;
+            ret=jniHelp.setVersion((char*) VERSION_FIELD_MCI, version.versionMci);
+            if(ret != ROOTPA_OK) return ret;
+            ret=jniHelp.setVersion((char*) VERSION_FIELD_SO, version.versionSo);
+            if(ret != ROOTPA_OK) return ret;
+            ret=jniHelp.setVersion((char*) VERSION_FIELD_MCLF, version.versionMclf);
+            if(ret != ROOTPA_OK) return ret;
+            ret=jniHelp.setVersion((char*) VERSION_FIELD_CONT, version.versionContainer);
+            if(ret != ROOTPA_OK) return ret;
+            ret=jniHelp.setVersion((char*) VERSION_FIELD_MCCONF, version.versionMcConfig);
+            if(ret != ROOTPA_OK) return ret;
+            ret=jniHelp.setVersion((char*) VERSION_FIELD_TLAPI, version.versionTlApi);
+            if(ret != ROOTPA_OK) return ret;
+            ret=jniHelp.setVersion((char*) VERSION_FIELD_DRAPI, version.versionDrApi);
+            if(ret != ROOTPA_OK) return ret;
+            ret=jniHelp.setVersion((char*) VERSION_FIELD_CMP, version.versionCmp);
+            if(tag!=2)
             {
-                ret=jniHelp.setVersion((char*) VERSION_FIELD_TAG1ALL, *((uint32_t*)version.productId));
-            }        
-            else
-            {
-                ret=jniHelp.setProductId((char*) version.productId);
-                if(ret != ROOTPA_OK) return ret;
-                ret=jniHelp.setVersion((char*) VERSION_FIELD_MCI, version.versionMci);
-                if(ret != ROOTPA_OK) return ret;
-                ret=jniHelp.setVersion((char*) VERSION_FIELD_SO, version.versionSo);
-                if(ret != ROOTPA_OK) return ret;
-                ret=jniHelp.setVersion((char*) VERSION_FIELD_MCLF, version.versionMclf);
-                if(ret != ROOTPA_OK) return ret;
-                ret=jniHelp.setVersion((char*) VERSION_FIELD_CONT, version.versionContainer);
-                if(ret != ROOTPA_OK) return ret;
-                ret=jniHelp.setVersion((char*) VERSION_FIELD_MCCONF, version.versionMcConfig);
-                if(ret != ROOTPA_OK) return ret;
-                ret=jniHelp.setVersion((char*) VERSION_FIELD_TLAPI, version.versionTlApi);
-                if(ret != ROOTPA_OK) return ret;
-                ret=jniHelp.setVersion((char*) VERSION_FIELD_DRAPI, version.versionDrApi);
-                if(ret != ROOTPA_OK) return ret;
-                ret=jniHelp.setVersion((char*) VERSION_FIELD_CMP, version.versionCmp);
+                LOGE("Java_com_gd_mobicore_pa_jni_CommonPAWrapper_getVersion unknown tag %d, version information may be wrong\n", tag);
+                ret=ROOTPA_ERROR_INTERNAL;
             }
         }
     }
@@ -406,8 +405,8 @@
     jobject jpath = envP->CallObjectMethod(obj, getFilesDirPath); 
     if(jpath!=NULL)
     {    
-        const char* pathP = envP->GetStringUTFChars((jstring)jpath, false);
-        setPaths(pathP);
+        const char* pathP = envP->GetStringUTFChars((jstring)jpath, NULL);
+        setPaths(pathP, CERT_PATH);
         if(NULL == pathP)
         {
             LOGE("setFilesPath pathP==NULL");    
@@ -433,7 +432,7 @@
 
 void copyElement(JNIEnv* envP, char** target, jstring source)
 {
-    const char* tmp=envP->GetStringUTFChars(source, false);
+    const char* tmp=envP->GetStringUTFChars(source, NULL);
     *target=(char*)malloc(strlen(tmp)+1);
     strcpy(*target, tmp);
     envP->ReleaseStringUTFChars(source, tmp);
@@ -576,3 +575,65 @@
 
     return ret;
 }
+
+char* addTrailingZero(uint8_t* vP, uint32_t length)
+{
+    char* newVP = new char[length+1];
+    if(NULL!=newVP)
+    {
+        memcpy(newVP, vP, length);
+        newVP[length]=0;
+    }
+    delete [] vP;    
+    return newVP;
+}
+
+JNIEXPORT void JNICALL Java_com_gd_mobicore_pa_jni_CommonPAWrapper_setEnvironmentVariable(JNIEnv* envP, jobject obj, jbyteArray variable_name, jbyteArray value)
+{
+    LOGD(">>Java_com_gd_mobicore_pa_jni_CommonPAWrapper_setEnvironmentVariable");
+    JniHelpers jniHelp(envP);
+    uint32_t length=0;    
+    char* envVarP=NULL;
+    char* envValP=NULL;
+    uint8_t*  vP=jniHelp.jByteArrayToCByteArray(variable_name, &length);
+    
+    if(NULL==vP)
+    {
+        LOGE("Java_com_gd_mobicore_pa_jni_CommonPAWrapper_setEnvironmentVariable, FAILURE: can not get variable\n");
+        return;
+    }
+
+    envVarP = addTrailingZero(vP, length);
+    if(value!=NULL)
+    {
+        vP=jniHelp.jByteArrayToCByteArray(value, &length);    
+        if(NULL!=vP)
+        {
+            envValP = addTrailingZero(vP, length);
+            if(envVarP && envValP)
+            {
+                LOGD("setting environment variable, %s %s", envVarP, envValP);
+                if(setenv(envVarP, envValP, 1)!=0)
+                {
+                    LOGE("Java_com_gd_mobicore_pa_jni_CommonPAWrapper_setEnvironmentVariable, setenv %s FAILURE\n", envVarP);
+                }
+            }
+        }
+        else
+        {
+            LOGE("Java_com_gd_mobicore_pa_jni_CommonPAWrapper_setEnvironmentVariable, FAILURE: can not get value\n");
+        }
+    }
+    else
+    {
+        LOGD("unsetting environment variable, %s", envVarP);        
+        if(unsetenv(envVarP)!=0)
+        {
+            LOGE("Java_com_gd_mobicore_pa_jni_CommonPAWrapper_setEnvironmentVariable, unsetenv %s FAILURE\n", envVarP);
+        }
+    }
+
+    delete[] envVarP;
+    delete[] envValP;
+    LOGD("<<Java_com_gd_mobicore_pa_jni_CommonPAWrapper_setEnvironmentVariable");
+}
diff --git a/rootpa/Code/Android/app/src/com/gd/mobicore/pa/jni/CommonPAWrapper.class b/rootpa/Code/Android/app/src/com/gd/mobicore/pa/jni/CommonPAWrapper.class
index 10e361f..f2b1889 100755
--- a/rootpa/Code/Android/app/src/com/gd/mobicore/pa/jni/CommonPAWrapper.class
+++ b/rootpa/Code/Android/app/src/com/gd/mobicore/pa/jni/CommonPAWrapper.class
Binary files differ
diff --git a/rootpa/Code/Android/app/src/com/gd/mobicore/pa/jni/CommonPAWrapper.java b/rootpa/Code/Android/app/src/com/gd/mobicore/pa/jni/CommonPAWrapper.java
index b75352d..9e97a1d 100755
--- a/rootpa/Code/Android/app/src/com/gd/mobicore/pa/jni/CommonPAWrapper.java
+++ b/rootpa/Code/Android/app/src/com/gd/mobicore/pa/jni/CommonPAWrapper.java
@@ -36,8 +36,7 @@
 
 package com.gd.mobicore.pa.jni;
 
-import android.util.Log;
-import android.content.Intent;
+import com.gd.mobicore.pa.service.Log;
 import android.os.Build;
 import android.os.Build.VERSION;
 import android.telephony.TelephonyManager;
@@ -69,6 +68,7 @@
     public native int doProvisioning(int uid, int spid, byte[] seAddress);
 	public native int installTrustlet(int dataType, byte[] tltOrKeyData, byte[] seAddress);
     public native int unregisterRootContainer(byte[] seAddress);
+    public native void setEnvironmentVariable(byte[] variable, byte[] value);    
 
     static{
         Log.d(TAG,"CommonPAWrapper.java: static");
@@ -124,5 +124,4 @@
         service_.trustletInstallCallback(trustlet);
         Log.d(TAG,"<<CommonPAWrapper.trustletInstallCallback");        
     }
-
 }
diff --git a/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/BaseService.java b/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/BaseService.java
index a7936be..702b640 100755
--- a/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/BaseService.java
+++ b/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/BaseService.java
@@ -33,8 +33,18 @@
 
 import android.app.Service;
 import android.content.Intent;
-import android.util.Log;
+import android.content.IntentFilter;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.net.NetworkInfo;
+import android.net.ConnectivityManager;
 
+import java.net.URI;
+import java.net.Proxy;
+import java.net.Proxy.Type;
+import java.net.ProxySelector;
+
+import java.util.List;
 import java.util.Timer;
 import java.util.TimerTask;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -43,7 +53,6 @@
 import com.gd.mobicore.pa.ifc.RootPAProvisioningIntents;
 import com.gd.mobicore.pa.ifc.CommandResult;
 
-
 public abstract class BaseService extends Service {
     protected static final String TAG = "RootPA-J";    
 
@@ -131,6 +140,80 @@
         return new CommandResult(CommandResult.ROOTPA_ERROR_LOCK);
     }
 
+    /**
+        Since libcurl is able to read and use proxy settings from http_proxy environment variable, we set the proxy here.
+        This should be changed every time the connection changes so that there are always correct proxy settings available
+    */
+
+    BroadcastReceiver networkChangeReceiver_=null;
+    protected void setupProxy()
+    {   
+        byte[] proxyAddress=null;
+        ProxySelector defaultProxySelector = ProxySelector.getDefault();
+
+        if(defaultProxySelector != null){
+            URI uri=null;
+            List<Proxy> proxyList=null;
+            try{
+                if(se_==null){
+                    uri=new URI("https://se.cgbe.trustonic.com"); // the URI here does not matter a lot, as long as one exists. We try to use as real one as is easily possible
+                }else{
+                    uri=new URI(new String(se_));                
+                }
+                proxyList = defaultProxySelector.select(uri);
+                if (proxyList.size() > 0)
+                {
+                    Proxy proxy = proxyList.get(0);
+                    Log.d(TAG,"BaseService.setupProxy proxy "+proxy); // there should be only one element in the list in the current Android versions, it is for the current connection 
+                    if(proxy != Proxy.NO_PROXY){
+                        Log.d(TAG,"BaseService.setupProxy proxy.type "+proxy.type());           
+                        if(proxy.type()==Proxy.Type.HTTP){
+                            // TODO-future there is currently no way for the user to store proxy user name and password in Android,
+                            // so they need to be asked at connection time. There is not any kind of user/password support for proxies in RootPA.
+                            // If we were able to get username/password we would add them to http(s)_proxy here.
+                            // if(username && password) proxyAddress=username+":"+password; (and add the next line just remove +1 from indexOf)
+                            proxyAddress=proxy.toString().substring(proxy.toString().indexOf("@")+1).getBytes();
+                        }
+                    }
+                }
+                
+            }catch(Exception e){
+                Log.e(TAG,"BaseService.setupProxy FAILURE in getting the proxy: "+e.toString());
+            }
+        }
+
+        commonPAWrapper().setEnvironmentVariable("http_proxy".getBytes(), proxyAddress);
+        commonPAWrapper().setEnvironmentVariable("https_proxy".getBytes(), proxyAddress);        
+        Log.d(TAG,"BaseService.setupProxy just set the proxy to: "+(proxyAddress==null?proxyAddress:new String(proxyAddress)));
+
+        // start listening to intents on network changes if not doing it already
+        // this is important since the proxy settings are network specific
+        if(networkChangeReceiver_==null){
+            networkChangeReceiver_=new BroadcastReceiver(){
+                public void onReceive(Context ctx, Intent intent){
+                    Log.d(TAG, "BaseService: Network connection changed");
+                    try{
+                        NetworkInfo ni=((ConnectivityManager)ctx.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
+                        if(ni!=null && ni.isConnectedOrConnecting()) {
+                            Log.d(TAG,"BaseService: Network "+ni.getTypeName()+" connected");
+                            setupProxy();
+                        }else{
+                            if(ni!=null){ 
+                                Log.d(TAG, "BaseService: network state "+ni.getState());
+                            }else{
+                                Log.d(TAG, "BaseService: no network info");
+                            }
+                        }
+                    }catch(Exception e){
+                        Log.e(TAG, "BaseService: Network connection change handling FAILURE "+e);
+                    }
+                }
+            };
+            IntentFilter filter=new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
+            registerReceiver(networkChangeReceiver_, filter);
+        }
+    }                     
+    
     protected synchronized boolean locked(int uid){
         return(lock_.get() != uid && uid != LOCK_FREE);
     }
@@ -140,11 +223,11 @@
     (trustlet connector/"sp.pa" for develope trustlet) that then can store it where desired.
     */
     public void trustletInstallCallback(byte[] trustlet){
-        Log.d(TAG,">>DeveloperService.trustletInstallCallback");
+        Log.d(TAG,">>BaseService.trustletInstallCallback");
         Intent intent=new Intent(RootPAProvisioningIntents.INSTALL_TRUSTLET);
         intent.putExtra(RootPAProvisioningIntents.TRUSTLET, trustlet);
         sendBroadcast(intent);
-        Log.d(TAG,"<<DeveloperService.trustletInstallCallback");        
+        Log.d(TAG,"<<BaseService.trustletInstallCallback");        
     }
     
     /**
@@ -201,7 +284,11 @@
                 intent=null; // no intent sent in this case
                 }catch(Exception e){
                     Log.e(TAG,"provisioningStateCallback releasing lock failed: "+e);
-                }            
+                }
+                if(networkChangeReceiver_!=null){
+                    unregisterReceiver(networkChangeReceiver_);
+                    networkChangeReceiver_=null;
+                }
                 break;
             default:
                 Log.e(TAG,"unknown state: "+state);
@@ -213,5 +300,12 @@
         }
 
         Log.d(TAG,"<<provisioningStateCallback ");
-    }    
+    }
+    
+    public void onDestroy(){
+        if(networkChangeReceiver_!=null){
+            unregisterReceiver(networkChangeReceiver_);
+            networkChangeReceiver_=null;
+        }
+    }
 }
\ No newline at end of file
diff --git a/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/DeveloperService.java b/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/DeveloperService.java
index 81b48c9..2e42bcf 100755
--- a/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/DeveloperService.java
+++ b/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/DeveloperService.java
@@ -35,7 +35,6 @@
 import android.content.Intent;
 import android.os.IBinder;
 import android.os.Bundle;
-import android.util.Log;
 
 import java.util.Random;
 
@@ -72,20 +71,15 @@
                 return new CommandResult(CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT);
             }
 
-            doProvisioningLockSuid_=DEVELOPER_UID_FOR_LOCK+new Random().nextInt(); // this may override the uid used in lock, which means it will not be 
-                                                                                   // properly released if doProvisioning or delete are running.
-                                                                                   // The timer will then release the lock
+            int tmpSuid=DEVELOPER_UID_FOR_LOCK+new Random().nextInt(); 
 
-            if(!DeveloperService.this.acquireLock(doProvisioningLockSuid_, false).isOk()){
+            if(!DeveloperService.this.acquireLock(tmpSuid, false).isOk()){
                 return new CommandResult(CommandResult.ROOTPA_ERROR_LOCK);
             }
-            
+            doProvisioningLockSuid_=tmpSuid;
             int err=0;
-            
             byte[] data=null;
             int dataType;            
-            
-            
             try{
                 if(trustletBinary != null){
                     data=trustletBinary;
@@ -94,7 +88,7 @@
                     data=key;
                     dataType=REQUEST_DATA_KEY;
                 }
-                    
+                setupProxy();    
                 err=commonPAWrapper().installTrustlet(dataType, data, se_);
             }catch(Exception e){
                 Log.e(TAG,"CommonPAWrapper().installTrustlet exception: ", e);
@@ -120,13 +114,16 @@
     }
 
     public void onDestroy(){
+        super.onDestroy();
         Log.d(TAG,"DeveloperService being destroyed");
     }
     
     @Override
     public IBinder onBind(Intent intent){
-        se_ = intent.getByteArrayExtra("SE");  // TODO-RELEASE: this makes sense at testing time, does it make sense in released code!!!
-        Log.d(TAG,"DeveloperService binding: "+new String(se_));
+        se_ = intent.getByteArrayExtra("SE");
+        Log.setLoggingLevel(intent.getIntExtra("LOG",0));
+        Log.i(TAG,"DeveloperService binding");
+        if(se_!=null) Log.d(TAG,new String(se_));
         return mBinder;
 
     }
diff --git a/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/Log.java b/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/Log.java
new file mode 100755
index 0000000..688fefe
--- /dev/null
+++ b/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/Log.java
@@ -0,0 +1,185 @@
+/*
+Copyright  © Trustonic Limited 2013
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice, this 
+     list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright notice, 
+     this list of conditions and the following disclaimer in the documentation 
+     and/or other materials provided with the distribution.
+
+  3. Neither the name of the Trustonic Limited nor the names of its contributors 
+     may be used to endorse or promote products derived from this software 
+     without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
+OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.gd.mobicore.pa.service;
+
+import java.lang.String;
+import java.lang.Throwable;
+
+public class Log {
+
+    private static int level_=android.util.Log.INFO;    
+    
+    /**
+    Set level of logging
+    */
+    public static void setLoggingLevel(int level){
+        if( level == android.util.Log.VERBOSE ||
+            level == android.util.Log.DEBUG ||
+            level == android.util.Log.INFO ||
+            level == android.util.Log.WARN ||
+            level == android.util.Log.ERROR ||
+            level == android.util.Log.ASSERT ){
+            level_=level;
+        }
+    }
+    
+    /**
+    Send a DEBUG log message.
+    */
+    public static int d(String tag, String msg){
+        if(level_<=android.util.Log.DEBUG) return android.util.Log.d(tag, msg);
+        return 0;
+    }    
+
+    /**
+    Send a DEBUG log message and log the exception.
+    */
+    public static int d(String tag, String msg, Throwable tr){
+        if(level_<=android.util.Log.DEBUG) return android.util.Log.d(tag, msg, tr);
+        return 0;        
+    }    
+
+    /**
+    Send an ERROR log message.
+    */
+    public static int e(String tag, String msg){
+        if(level_<=android.util.Log.ERROR) return android.util.Log.e(tag, msg);
+        return 0;        
+    }
+
+    /**
+    Send a ERROR log message and log the exception.
+    */    
+    public static int e(String tag, String msg, Throwable tr){
+        if(level_<=android.util.Log.ERROR) return android.util.Log.e(tag, msg, tr);
+        return 0;        
+    }
+
+    /**
+    Send an INFO log message.    
+    */    
+    public static int i(String tag, String msg){
+        if(level_<=android.util.Log.INFO) return android.util.Log.i(tag, msg);
+        return 0;        
+    }
+
+    /**
+    Send a INFO log message and log the exception.
+    */
+    public static int i(String tag, String msg, Throwable tr){
+        if(level_<=android.util.Log.INFO) return android.util.Log.i(tag, msg, tr);
+        return 0;        
+    }
+
+    /**
+    Handy function to get a loggable stack trace from a Throwable
+    */
+    public static String getStackTraceString(Throwable tr){
+        return android.util.Log.getStackTraceString(tr);
+    }
+    
+    /**
+    Checks to see whether or not a log for the specified tag is loggable at the specified level.
+    */
+    public static boolean isLoggable(String tag, int level){
+        return android.util.Log.isLoggable(tag, level);
+    }
+
+    /**    
+    Low-level logging call.
+    */
+    public static int println(int priority, String tag, String msg){
+        return android.util.Log.println(priority, tag, msg);
+    }
+
+    /**
+    Send a VERBOSE log message.
+    */
+    public static int v(String tag, String msg){
+        if(level_<=android.util.Log.VERBOSE) return android.util.Log.v(tag, msg);
+        return 0;        
+    }
+
+    /**
+    Send a VERBOSE log message and log the exception.
+    */
+    public static int v(String tag, String msg, Throwable tr){
+        if(level_<=android.util.Log.VERBOSE) return android.util.Log.v(tag, msg, tr);
+        return 0;        
+    }
+
+    /**
+    Log the exception at WARN level
+    */
+
+    public static int w(String tag, Throwable tr){
+        if(level_>=android.util.Log.WARN) return android.util.Log.w(tag, tr);
+        return 0;        
+    }
+
+    /**
+    Send a WARN log message and log the exception.
+    */
+    public static int w(String tag, String msg, Throwable tr){
+        if(level_<=android.util.Log.WARN) return android.util.Log.w(tag, msg, tr);
+        return 0;            
+    }
+
+    /**
+    Send a WARN log message.
+    */
+    public static int w(String tag, String msg){
+        if(level_<=android.util.Log.WARN) return android.util.Log.w(tag, msg);
+        return 0;        
+    }
+
+    /**
+    What a Terrible Failure: Report an exception that should never happen.
+    */
+    public static int wtf(String tag, Throwable tr){
+        return android.util.Log.wtf(tag, tr);
+    }
+
+    /**
+    What a Terrible Failure: Report a condition that should never happen.
+    */
+    public static int wtf(String tag, String msg){
+        return android.util.Log.wtf(tag, msg);
+    }
+
+    /**
+    What a Terrible Failure: Report an exception that should never happen.
+    */
+    public static int wtf(String tag, String msg, Throwable tr){
+        return android.util.Log.wtf(tag, msg, tr);
+    }
+}
\ No newline at end of file
diff --git a/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/OemService.java b/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/OemService.java
index 2c3261c..47e5e5b 100755
--- a/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/OemService.java
+++ b/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/OemService.java
@@ -35,7 +35,6 @@
 import android.content.Intent;
 import android.os.IBinder;
 import android.os.Bundle;
-import android.util.Log;
 
 import java.util.Random;
 
@@ -65,19 +64,20 @@
         public CommandResult unregisterRootContainer(){
             Log.d(TAG,">>RootPAServiceIfc.Stub.unregisterRootContainer"); 
 
-            doProvisioningLockSuid_=OEM_UID_FOR_LOCK+new Random().nextInt(); // this may override the uid used in lock, which means it will not be
+            int tmpSuid=OEM_UID_FOR_LOCK+new Random().nextInt(); // this may override the uid used in lock, which means it will not be
             
-            if(!OemService.this.acquireLock(doProvisioningLockSuid_, false).isOk()){
+            if(!OemService.this.acquireLock(tmpSuid, false).isOk()){
                 return new CommandResult(CommandResult.ROOTPA_ERROR_LOCK);
             }
 
+            doProvisioningLockSuid_=tmpSuid;
             Log.d(TAG,"RootPAServiceIfc.Stub.unregisterRootContainer calling JNI");
             
             boolean[] isRegistered = new boolean[1];
             int ret=CommandResult.ROOTPA_OK;
 
             try{
-                   
+                setupProxy();
             	ret=commonPAWrapper().unregisterRootContainer(se_);
             }catch(Exception e){
                 Log.e(TAG,"CommonPAWrapper().unregisterRootContainer exception: ", e);
@@ -111,15 +111,17 @@
     }
 
     public void onDestroy(){
+        super.onDestroy();        
         Log.d(TAG,"OemService being destroyed");
     }
     
     @Override
     public IBinder onBind(Intent intent){
-        se_ = intent.getByteArrayExtra("SE");  // TODO-RELEASE: this makes sense at testing time, does it make sense in released code!!!
-        Log.d(TAG,"OemService binding: "+new String(se_));
+        se_ = intent.getByteArrayExtra("SE");
+        Log.setLoggingLevel(intent.getIntExtra("LOG",0));
+        Log.i(TAG,"OemService binding");
+        if(se_!=null) Log.d(TAG,new String(se_));
         return mBinder;
-
     }
 
     @Override
diff --git a/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/ProvisioningService.java b/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/ProvisioningService.java
index d72c08f..c13f311 100755
--- a/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/ProvisioningService.java
+++ b/rootpa/Code/Android/app/src/com/gd/mobicore/pa/service/ProvisioningService.java
@@ -35,7 +35,6 @@
 import android.content.Intent;
 import android.os.IBinder;
 import android.os.Bundle;
-import android.util.Log;
 
 import java.util.List;
 import java.util.ArrayList;
@@ -78,27 +77,37 @@
         
         public CommandResult executeCmpCommands(int uid, List<CmpCommand> commands, List<CmpResponse> responses){
 
-            Log.d(TAG,">>RootPAServiceIfc.Stub.executeCmpCommands"); 
+            Log.d(TAG,">>RootPAServiceIfc.Stub.executeCmpCommands "+commands+" "+responses); 
 
+            if(commands==null||responses==null){ // having null out variable leads to null pointer exception in the client, however we still want to do checking so that there is not unncessary execution of the following code
+                Log.d(TAG,"RootPAServiceIfc.Stub.executeCmpCommands, illegal argument"); 
+                return new CommandResult(CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT);
+            }            
+            
             if(locked(uid)){
                 return new CommandResult(CommandResult.ROOTPA_ERROR_LOCK);
             }
             
-            int err=0;
+            int ret=CommandResult.ROOTPA_OK;
             try{
-                err=commonPAWrapper().executeCmpCommands(uid, commands, responses);
+                ret=commonPAWrapper().executeCmpCommands(uid, commands, responses);
             }catch(Exception e){
                 Log.e(TAG,"CommonPAWrapper().executeCmpCommands exception: ", e);
-                err=CommandResult.ROOTPA_ERROR_INTERNAL;
+                ret=CommandResult.ROOTPA_ERROR_INTERNAL;
             }
 
             Log.d(TAG,"<<RootPAServiceIfc.Stub.executeCmpCommands");
-            return new CommandResult(err);
+            return new CommandResult(ret);
         }
         
         public CommandResult isRootContainerRegistered(BooleanResult result){
             Log.d(TAG,">>RootPAServiceIfc.Stub.isRootContainerRegistered"); 
 
+            if(result==null){  // having null out variable leads to null pointer exception in the client, however we stll want to do checking so that there is not unncessary execution of the following code
+                Log.d(TAG,"RootPAServiceIfc.Stub.isRootContainerRegistered result null");
+                return new CommandResult(CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT);
+            }  
+            
             int internalUidForLock=new Random().nextInt();
             
             if(!ProvisioningService.this.acquireLock(internalUidForLock, false).isOk())
@@ -130,6 +139,12 @@
 
         public CommandResult isSPContainerRegistered(SPID spid, BooleanResult result){
             Log.d(TAG,">>RootPAServiceIfc.Stub.isSPContainerRegistered"); 
+
+            if(spid==null || result==null){  // having null out variable leads to null pointer exception in the client, however we still want to do checking so that there is not unncessary execution of the following code
+                Log.d(TAG,"RootPAServiceIfc.Stub.isSPContainerRegistered spid "+spid+" result "+result);
+                return new CommandResult(CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT);
+            }
+
             boolean[] isRegistered = new boolean[1];
             int ret=CommandResult.ROOTPA_OK;
 
@@ -169,23 +184,23 @@
                 return new CommandResult(CommandResult.ROOTPA_ERROR_LOCK);
             }
 
-            int err=CommandResult.ROOTPA_OK;
+            int ret=CommandResult.ROOTPA_OK;
             byte[] productId=new byte[64]; // max length of product id from mcVersionInfo.h
             Bundle versionBundle= new Bundle();
             List<String> keys = new ArrayList<String>();
             List<Integer> values = new ArrayList<Integer>();
 
             try{
-                err=commonPAWrapper().getVersion(productId, keys, values);
-                if(err == CommandResult.ROOTPA_OK && (keys.size() != values.size())){
-                    err=CommandResult.ROOTPA_ERROR_INTERNAL;                
+                ret=commonPAWrapper().getVersion(productId, keys, values);
+                if(ret == CommandResult.ROOTPA_OK && (keys.size() != values.size())){
+                    ret=CommandResult.ROOTPA_ERROR_INTERNAL;                
                 }
             }catch(Exception e){
                 Log.e(TAG,"CommonPAWrapper().getVersion exception: ", e);
-                err=CommandResult.ROOTPA_ERROR_INTERNAL;
+                ret=CommandResult.ROOTPA_ERROR_INTERNAL;
             }
 
-            if(err==CommandResult.ROOTPA_OK){
+            if(ret==CommandResult.ROOTPA_OK){
                 version.setProductId(new String(productId).trim());
 
                 for(int i=0; i<values.size(); i++){
@@ -203,8 +218,8 @@
                 // we leave it the the next command if the problem remains
             }                    
 
-            Log.d(TAG,"<<RootPAServiceIfc.Stub.getVersion "+err); 
-            return new CommandResult(err);
+            Log.d(TAG,"<<RootPAServiceIfc.Stub.getVersion "+ret); 
+            return new CommandResult(ret);
         }
 
 
@@ -255,16 +270,15 @@
             // we do not use uid here since we do not want to let the client to released the lock, it is done 
             // internally at CommonPAWrapper.java when sending Intents. 
             
-            doProvisioningLockSuid_=uid+PROVISIONING_UID_FOR_LOCK; // this may override the uid used in lock, which means it will not be 
-                                                                   // properly released if installTrustlet or delete are running.
-                                                                   // The timer will then release the lock.
+            int tmpSuid=uid+PROVISIONING_UID_FOR_LOCK+new Random().nextInt();
 
-
-            if(!ProvisioningService.this.acquireLock(doProvisioningLockSuid_, false).isOk()){
+            if(!ProvisioningService.this.acquireLock(tmpSuid, false).isOk()){
                 return new CommandResult(CommandResult.ROOTPA_ERROR_LOCK);
             }
-
+            doProvisioningLockSuid_=tmpSuid;
+            
             try{
+                setupProxy();
                 ret=commonPAWrapper().doProvisioning(uid, spid.spid(), se_);
             }catch(Exception e){
                 Log.d(TAG,"CommonPAWrapper()).doProvisioning failed "+e);
@@ -286,12 +300,16 @@
         public CommandResult getSPContainerStructure(SPID spid, SPContainerStructure cs){
             Log.d(TAG,">>RootPAServiceIfc.Stub.getSPContainerStructure"); 
 
+            if(spid==null||cs==null){ // having null out variable leads to null pointer exception in the client, however we still want to do checking so that there is not unncessary execution of the following code
+                return new CommandResult(CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT);
+            }            
+            
             int internalUidForLock=new Random().nextInt();
             if(!ProvisioningService.this.acquireLock(internalUidForLock, false).isOk())
             {
                 return new CommandResult(CommandResult.ROOTPA_ERROR_LOCK);
             }
-
+            
             int ret=CommandResult.ROOTPA_OK;
 
             final int CONTAINER_STATE_IDX=0;
@@ -367,6 +385,10 @@
         public CommandResult getSPContainerState(SPID spid, SPContainerStateParcel state){
             Log.d(TAG,">>RootPAServiceIfc.Stub.getSPContainerState"); 
 
+            if(spid==null||state==null){ // having null out variable leads to null pointer exception in the client, however we still want to do checking so that there is not unncessary execution of the following code
+                return new CommandResult(CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT);
+            }
+
             int internalUidForLock=new Random().nextInt();
             if(!ProvisioningService.this.acquireLock(internalUidForLock, false).isOk())
             {
@@ -393,7 +415,7 @@
                     ret=CommandResult.ROOTPA_ERROR_INTERNAL;                
                 }
             }else if (ret==CommandResult.ROOTPA_ERROR_INTERNAL_NO_CONTAINER){
-           	    state.setEnumeratedValue(SPContainerState.DOES_NOT_EXIST);            
+           	    state.setEnumeratedValue(SPContainerState.DOES_NOT_EXIST);
                 ret=CommandResult.ROOTPA_OK;
             }
 
@@ -476,17 +498,20 @@
     @Override
     public void onLowMemory() {
         Log.d(TAG,"ProvisioningService onLowMemory");
-        super.onLowMemory();    
+        super.onLowMemory();
     }
 
     public void onDestroy(){
+        super.onDestroy();        
         Log.d(TAG,"ProvisioningService being destroyed");
     }
     
     @Override
     public IBinder onBind(Intent intent){
-        se_ = intent.getByteArrayExtra("SE");  // TODO-RELEASE: this makes sense at testing time, does it make sense in released code!!!
-        Log.d(TAG,"ProvisioningService binding: "+new String(se_));
+        se_ = intent.getByteArrayExtra("SE");
+        Log.setLoggingLevel(intent.getIntExtra("LOG",0));
+        Log.i(TAG,"ProvisioningService binding");
+        if(se_!=null) Log.d(TAG,new String(se_));
         return mBinder;
     }
 
diff --git a/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/CommandResult.java b/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/CommandResult.java
index 379e3ab..b082e36 100755
--- a/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/CommandResult.java
+++ b/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/CommandResult.java
@@ -145,6 +145,10 @@
         return result_;
     }
 
+    public void setValue(int value){
+        result_=value;
+    }    
+    
     public boolean isOk(){
         return (result_==ROOTPA_OK);
     }
diff --git a/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/RootPAProvisioningIntents.java b/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/RootPAProvisioningIntents.java
index 0936873..5cd437e 100755
--- a/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/RootPAProvisioningIntents.java
+++ b/rootpa/Code/Android/lib/src/com/gd/mobicore/pa/ifc/RootPAProvisioningIntents.java
@@ -35,6 +35,14 @@
  * A list of intent actions that the root PA can broadcast.

  */

 public class RootPAProvisioningIntents {

+

+//    

+/** Intents for starting up and connecitng to services  */

+//

+

+    public static final String PROVISIONING_SERVICE="com.gd.mobicore.pa.service.PROVISIONING_SERVICE";

+    public static final String DEVELOPER_SERVICE="com.gd.mobicore.pa.service.DEVELOPER_SERVICE";

+    public static final String OEM_SERVICE="com.gd.mobicore.pa.service.OEM_SERVICE";

 	

 //    

 /** Execution status reporting Intents   */

@@ -47,7 +55,6 @@
 /** root provisioning has completed, root and SP containers are available for use */

     public static final String FINISHED_ROOT_PROVISIONING = "com.gd.mobicore.pa.service.PROVISIONING_FINISHED";

 

-// Execution status reporting Intents

     

 /** this intent contains developer trustlet in it's extra data. The trustlet has been signed by SE */

     public static final String INSTALL_TRUSTLET = "com.gd.mobicore.pa.service.INSTALL_TRUSTLET";

@@ -79,6 +86,5 @@
 /** unregistering root container will be sent by SE after OemService.unregisterRootContainer is used */

     public static final int UNREGISTERING_ROOT_CONTAINER=3000;

 

-

 	private RootPAProvisioningIntents() { }

 }

diff --git a/rootpa/Code/Common/cacerts.h b/rootpa/Code/Common/cacerts.h
new file mode 100755
index 0000000..6769a5d
--- /dev/null
+++ b/rootpa/Code/Common/cacerts.h
@@ -0,0 +1,80 @@
+/*
+Copyright  © Trustonic Limited 2013
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice, this 
+     list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright notice, 
+     this list of conditions and the following disclaimer in the documentation 
+     and/or other materials provided with the distribution.
+
+  3. Neither the name of the Trustonic Limited nor the names of its contributors 
+     may be used to endorse or promote products derived from this software 
+     without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
+OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef CACERTS_H
+#define CACERTS_H
+
+#define CA_CERTIFICATES \
+"Trustonic Root CA, expires Feb 21 16:36:51 2038 GMT\n\
+================================================================\n\
+-----BEGIN CERTIFICATE-----\n\
+MIIDcjCCAlqgAwIBAgIEEjRWADANBgkqhkiG9w0BAQsFADA/MQswCQYDVQQGEwJV\n\
+SzEaMBgGA1UECgwRVHJ1c3RvbmljIExpbWl0ZWQxFDASBgNVBAMMC1RMUyBSb290\n\
+IENBMB4XDTEzMDIyNzE2MzY1MVoXDTM4MDIyMTE2MzY1MVowPzELMAkGA1UEBhMC\n\
+VUsxGjAYBgNVBAoMEVRydXN0b25pYyBMaW1pdGVkMRQwEgYDVQQDDAtUTFMgUm9v\n\
+dCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMaJYI6y7hxdxBoI\n\
+nTkiYhL2qhBtD0Kcmfx+NTiUUkO+9u9qSyzbsN7kfgpsLO8Eq3AGg72zEjayXDfz\n\
+mlHW1CnO/0nWDiM4b4hDhpJRspE2BCnKvAHAvcQeGpzX5hhZLYh51Zrn/pOLCvoR\n\
+9XV1inlw6M0+M9A5n11l6tEEWGbgWRnna+LJFX+bSGnihP1Be2nHsVnqcIDMo/hz\n\
+Cj2ZX2G95e+UVPIc9JK/SVqFzYHltNjUyOFG7jGOncDhdG9vgHUoiikr6ZF7NHao\n\
+vqxhIOiiK2tDVos//3/PgjrVwPkAJlVenMLpfEdxCtwyHO2frQpmkHc1eWFD5NGd\n\
+8vzh2qECAwEAAaN2MHQwHQYDVR0OBBYEFE9Csq2lSvztAMSjVdll4sxTPwvbMB8G\n\
+A1UdIwQYMBaAFE9Csq2lSvztAMSjVdll4sxTPwvbMA8GA1UdEwEB/wQFMAMBAf8w\n\
+DgYDVR0PAQH/BAQDAgIEMBEGCWCGSAGG+EIBAQQEAwICBDANBgkqhkiG9w0BAQsF\n\
+AAOCAQEAQrnIh4jpJtNf6hqnCpmwmQFD4456gFh0B3cmQnVvkfDCApJ+9G3xSsaL\n\
+8LJRvK6c/pAV9p+0pvh3ftV4MFSw9AytZrihsrVykxlI1UGRHJmDO1hRh5QlfbMV\n\
+fstHI0W8ec2Al41g3C9pM+FgBBKIoG6ewpDlaUbMXk8033jf/OIyF5HTeQYqr788\n\
+/ykFY32Mz0lpC2GdIeRThlK4ka63WuffdtKAayyPcitMeZtajJpa7s02MZF9Dd5s\n\
+hISypnUvXAN/BZXIwQXSAOqajTGEv3X/wLyasm3nkEX29IgDvknLBoqnTS9rD2LQ\n\
+4BnqNQubr5XROBOlwdkrHTveN4Y9pA==\n\
+-----END CERTIFICATE-----\n\
+\n\
+Self signed certificate for 10.0.2.2 for RootPA testing purposes\n\
+================================================================\n\
+-----BEGIN CERTIFICATE-----\n\
+MIICyTCCAbGgAwIBAgIJAPJnq4Q6g6GlMA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNV\n\
+BAMTCXRlcm9ua29uZTAeFw0xMzAyMjAwODM4MzBaFw0yMzAyMTgwODM4MzBaMBQx\n\
+EjAQBgNVBAMTCXRlcm9ua29uZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\n\
+ggEBANTqu+e+gvW7fzoq59DlM2z4kWLYfGKY0DKs8dB15uo1p3tAEn/SWxTE5s8t\n\
+HxW7ui7fs5JL8AC/94jCAbeN/xPJBf4nVdjnlg19fWiylcq4Ib+FxhCar6bu/a2W\n\
+uUvI8IuM42Z8uyybBRVv8Q1Sqn+O4YiPfvVi+7oAu0pE1vemlXZ7SyXecBBtqBpy\n\
+sWfW2lV4ixeLqSay9o/ZgHRdUdkZorv/eDpLlVIwo7zmQsLb0jbGMlfRATsNkYI8\n\
+IEOxPdJSIUjnY+tZcMYQniCc0CnxWIMAxWJxMgQchyCQPkNAStwEsO0Ty3NJKGfr\n\
+mMHIzc58x999i+MeZ80AWbLjjX0CAwEAAaMeMBwwCQYDVR0TBAIwADAPBgNVHREE\n\
+CDAGhwQKAAICMA0GCSqGSIb3DQEBBQUAA4IBAQACnClBnUXBUf+GmFlq2F+8k4m1\n\
+0A9q+7Krk56JgqzdBMy8SO7FHnsyd2azWoqXzSuJyVsTMfCD0xfWXKSdzJJPJvUR\n\
+SYNQxYNUWbVKfXjXQnALltR7D+IvHWCukeohBx3nPjnFzfb68xyr2809RTEdYFyq\n\
+3olggSjYDRiX+n1XP8ryx/l10X8M9cKkLXsa9o8bSyYrpxPuYPCM6bD9g2xriAO+\n\
+1irwp3fWWFcm1oedSSNv8E9AiZuevuliT5+0BtoXY11NE+ipPKDtJUVuo2gHRcqo\n\
+/92iZY4T5y0ERhZ2jnRB5k6xdb94EdL2aSBmz6XXbr7thAE29HUwkprKYaAt\n\
+-----END CERTIFICATE-----\n"
+
+#endif
+//CACERTS_H
\ No newline at end of file
diff --git a/rootpa/Code/Common/commandhandler.c b/rootpa/Code/Common/commandhandler.c
index 387c4c3..926e9e2 100755
--- a/rootpa/Code/Common/commandhandler.c
+++ b/rootpa/Code/Common/commandhandler.c
@@ -42,6 +42,8 @@
 #include "contentmanager.h"
 #include "provisioningengine.h"
 #include "xmlmessagehandler.h"
+#include "seclient.h"
+
 
 #define GET_VERSION_COMMAND_LENGTH 4
 #define GET_SUID_COMMAND_LENGTH 4
@@ -99,16 +101,14 @@
         else
         {
             *tag=((cmpRspGetVersion_t*)(response.contentP))->tag;
-            if(CMP_VERSION_TAG1 == *tag)
-            {
-                *((uint32_t*)versionP->productId)=((cmpRspGetVersion_t*)(response.contentP))->data.versionData1.number;
-            }
-            else if (CMP_VERSION_TAG2 == *tag)
+
+            if (CMP_VERSION_TAG2 == *tag)
             {
                 memcpy(versionP, &((cmpRspGetVersion_t*)(response.contentP))->data.versionData2.versionInfo, sizeof(*versionP));
             }
             else
             {
+                LOGE("getVersion, unsupported version tag %d", *tag);
                 ret=ROOTPA_ERROR_INTERNAL;
             }
         }
@@ -209,9 +209,9 @@
     if(NULL==isRegisteredP) return ROOTPA_ERROR_ILLEGAL_ARGUMENT;
 
     int state;
-    mcResult_t result=getSpContainerState(spid, &state);
+    ret=getSpContainerState(spid, &state);
     
-    if(MC_DRV_OK == result)
+    if(ROOTPA_OK == ret)
     {
         if(state != MC_CONT_STATE_UNREGISTERED)
         {
@@ -222,13 +222,10 @@
             *isRegisteredP=false;        
         }
     }
-    else if(MC_DRV_ERR_INVALID_DEVICE_FILE == result)
+    else if(ROOTPA_ERROR_INTERNAL_NO_CONTAINER == ret)
     {
-        *isRegisteredP=false;    
-    }
-    else
-    {
-        ret=ROOTPA_ERROR_REGISTRY;
+        *isRegisteredP=false;
+        ret=ROOTPA_OK;
     }
     
     LOGD("<<isSpContainerRegistered %d", *isRegisteredP);
@@ -247,13 +244,12 @@
     
     if(MC_DRV_ERR_INVALID_DEVICE_FILE == result)
     {
-        ret=ROOTPA_ERROR_INTERNAL_NO_CONTAINER;
+        ret=ROOTPA_ERROR_INTERNAL_NO_CONTAINER; // using this since it is changed to ROOTPA_OK and state NO_CONTAINER in the wrapper.
     }
     else if (result!=MC_DRV_OK)
     {
         ret=ROOTPA_ERROR_REGISTRY;
     }
-    
 
     LOGD("<<getSpContainerState %d", *stateP);
     return ret;
@@ -292,7 +288,7 @@
                 if(ROOTPA_OK == ret)
                 {
                     uint32_t tltContSize=0;
-                    result=regReadTlt(&spP->cont.children[i], &tltP, &tltContSize);
+                    result=regReadTlt(&spP->cont.children[i], &tltP, &tltContSize, spid);
                     if(MC_DRV_OK == result)
                     {
                         spContainerStructure->tltContainers[spContainerStructure->nbrOfTlts].state=((mcTltContCommon_t*)(((uint8_t*)tltP)+sizeof(mcSoHeader_t)))->attribs.state;
@@ -311,7 +307,7 @@
     }
     else if(MC_DRV_ERR_INVALID_DEVICE_FILE == result)
     {
-        ret=ROOTPA_ERROR_INTERNAL_NO_CONTAINER;
+        ret=ROOTPA_ERROR_INTERNAL_NO_CONTAINER; // using this since it is changed to ROOTPA_OK and state NO_CONTAINER in the wrapper.
     }
     else 
     {
@@ -485,16 +481,16 @@
     return setInitialAddress(addrP, length);
 }
 
-void setPaths(const char* storageDirP)
+void setPaths(const char* storageDirP, const char* certDirP)
 {
     setXsdPaths(storageDirP);
+    setCertPath(storageDirP, certDirP);
 }
 
 rootpaerror_t unregisterRootContainer(CallbackFunctionP callbackP, SystemInfoCallbackFunctionP systemInfoCallbackP)
 {
     LOGD("unregisterRootContainer");
 
-
 	mcSpid_t spid;
 	memset(&spid, 0x0, sizeof(mcSpid_t));
 	return provision(spid, callbackP, systemInfoCallbackP, NULL, initialRel_DELETE);
diff --git a/rootpa/Code/Common/contentmanager.c b/rootpa/Code/Common/contentmanager.c
index c66d303..21ab9f4 100755
--- a/rootpa/Code/Common/contentmanager.c
+++ b/rootpa/Code/Common/contentmanager.c
@@ -109,6 +109,10 @@
                 {
                     // returning actual error in case of the command failed
                     ret=iRet;
+                    if(ROOTPA_OK==responsesP[i].hdr.ret)
+                    {
+                        responsesP[i].hdr.ret=ret;
+                    }
                     
                     if(commandsP[i].hdr.ignoreError==false)
                     {
@@ -189,6 +193,8 @@
         {
             LOGE("executeOneCmpCommand not able to map memory %d", mcRet);
             ret=ROOTPA_ERROR_MOBICORE_CONNECTION;
+            commandP->hdr.intRet=mcRet;
+            responseP->hdr.intRet=mcRet;
             break;
         }
 
@@ -198,9 +204,11 @@
             break;
         }
 
-        if (unlikely( !tltChannelTransmit(handle, MC_INFINITE_TIMEOUT))) // TODO-RELEASE is infinite timeout ok here?
+        if (unlikely( !tltChannelTransmit(handle, NOTIFICATION_WAIT_TIMEOUT_MS)))
         {
-            ret=ROOTPA_ERROR_MOBICORE_CONNECTION; 
+            ret=ROOTPA_ERROR_MOBICORE_CONNECTION;
+            commandP->hdr.intRet=handle->lasterror;
+            responseP->hdr.intRet=handle->lasterror;
             break;
         }
 
@@ -232,6 +240,8 @@
         {
             LOGE("executeOneCmpCommand not able to free mapped memory %d", mcRet);
             ret=ROOTPA_ERROR_MOBICORE_CONNECTION;
+            commandP->hdr.intRet=mcRet;
+            responseP->hdr.intRet=mcRet;
             break;
         }
 
@@ -258,6 +268,7 @@
     LOGD("freeing mapped memory %ld", (long int) handle->mappedP);    
     free(handle->mappedP);    
     if(commandP->hdr.ret==ROOTPA_OK) commandP->hdr.ret=ret;
+    if(responseP->hdr.ret==ROOTPA_OK) responseP->hdr.ret=ret;    
     LOGD("<<executeOneCmpCommand %d %d",commandId, ret);
     return ret;
 }
diff --git a/rootpa/Code/Common/contentmanager.h b/rootpa/Code/Common/contentmanager.h
index 37780a3..57b4d66 100755
--- a/rootpa/Code/Common/contentmanager.h
+++ b/rootpa/Code/Common/contentmanager.h
@@ -34,6 +34,8 @@
 
 #include "rootpa.h"
 
+#define NOTIFICATION_WAIT_TIMEOUT_MS 3000 // wait for 3 seconds max
+
 rootpaerror_t executeContentManagementCommands(int numberOfCommands, CmpMessage* commandsP, CmpMessage* responsesP, uint32_t* internalError);
 rootpaerror_t uploadSo(uint8_t* containerDataP, uint32_t containerLength, uint32_t* regRetP);
 rootpaerror_t openCmtlSession();
diff --git a/rootpa/Code/Common/enrollmentservicexmlschema.h b/rootpa/Code/Common/enrollmentservicexmlschema.h
index 00be119..4210f04 100755
--- a/rootpa/Code/Common/enrollmentservicexmlschema.h
+++ b/rootpa/Code/Common/enrollmentservicexmlschema.h
@@ -69,11 +69,9 @@
 			<xsd:enumeration value=\"INTERNAL_ERROR\" /> \
 			<xsd:enumeration value=\"BUSY_ERROR\" /> \
 			<xsd:enumeration value=\"REGISTRY_ERROR\" /> \
+            <xsd:enumeration value=\"REGISTRY_OBJECT_NOT_AVAILABLE\" /> \
 			<xsd:enumeration value=\"MOBICORE_CONNECTION_ERROR\" /> \
 			<xsd:enumeration value=\"OUT_OF_MEMORY_ERROR\" /> \
-			<xsd:enumeration value=\"COMMAND_EXECUTION_ERROR\" /> \
-			<xsd:enumeration value=\"ILLEGAL_ARGUMENT_ERROR\" /> \
-			<xsd:enumeration value=\"NETWORK_ERROR\" /> \
 			<xsd:enumeration value=\"XML_ERROR\" /> \
         </xsd:restriction> \
 	</xsd:simpleType> \
diff --git a/rootpa/Code/Common/include/logging.h b/rootpa/Code/Common/include/logging.h
index 95b9213..0b2f28b 100755
--- a/rootpa/Code/Common/include/logging.h
+++ b/rootpa/Code/Common/include/logging.h
@@ -39,14 +39,18 @@
     #define LOGE(...)	__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
     #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))
     #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
-    #define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
+    #ifdef __DEBUG    
+        #define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
+    #else
+        #define LOGD(scite ...)
+    #endif     
 #else
     #include <stdio.h>
 
     #define LOGE(fmt, ...)  printf(fmt "\n", ##__VA_ARGS__)    
     #define LOGW(fmt, ...)  printf(fmt "\n", ##__VA_ARGS__)    
     #define LOGI(fmt, ...)  printf(fmt "\n", ##__VA_ARGS__)    
-    #ifdef DEBUG
+    #ifdef __DEBUG
         #define LOGD(fmt, ...)  printf(fmt "\n", ##__VA_ARGS__)
     #else
         #define LOGD(fmt, ...)
diff --git a/rootpa/Code/Common/include/provisioningagent.h b/rootpa/Code/Common/include/provisioningagent.h
index 98b6aa5..fb3b19d 100755
--- a/rootpa/Code/Common/include/provisioningagent.h
+++ b/rootpa/Code/Common/include/provisioningagent.h
@@ -195,24 +195,6 @@
 */
 rootpaerror_t installTrustlet(mcSpid_t spid, CallbackFunctionP callbackP, SystemInfoCallbackFunctionP systemInfoCallbackP, trustletInstallationData_t* dataP);
 
-/**
-This is helper function for the platform dependent part to inform the platform independent part 
-on the file storage location
-
-@param storageDirP NULL terminated char array containing the path to the storage location
-*/
-
-void setPaths(const char* storageDirP);
-
-/**
-This is helper function for setting SE address. 
-
-@param addrP pointer to the address, it can but does not need to be null terminated. The address needs 
-       to begin with "http(s)://" and end with "/".
-@param length length of the address
-@return ROOTPA_OK is setting succeeded, an error code otherwise
-*/
-rootpaerror_t setSeAddress(const char* addrP, uint32_t length);
 
 /**
 This is helper function for unregistering root container.
@@ -230,6 +212,27 @@
 */
 rootpaerror_t unregisterRootContainer(CallbackFunctionP callbackP, SystemInfoCallbackFunctionP systemInfoCallbackP);
 
+/**
+This is helper function for the platform dependent part to inform the platform independent part 
+on the file storage location
+
+@param storageDirP NULL terminated char array containing the path to the storage location
+@param certDirP NULL terminated char array containing the path to the location where ssl should look for ce certificates.
+  note that since the certificates are also hardcoded, it is possible that this path is not used, however it must be given anyway
+*/
+
+void setPaths(const char* storageDirP, const char* certDirP);
+
+/**
+This is helper function for setting SE address. 
+
+@param addrP pointer to the address, it can but does not need to be null terminated. The address needs 
+       to begin with "http(s)://" and end with "/".
+@param length length of the address
+@return ROOTPA_OK is setting succeeded, an error code otherwise
+*/
+rootpaerror_t setSeAddress(const char* addrP, uint32_t length);
+
 #ifdef __cplusplus
 } 
 #endif
diff --git a/rootpa/Code/Common/pacmp3.c b/rootpa/Code/Common/pacmp3.c
index 7f1304c..7d8860b 100755
--- a/rootpa/Code/Common/pacmp3.c
+++ b/rootpa/Code/Common/pacmp3.c
@@ -70,14 +70,12 @@
     return ((cmpResponseHeader_t*)cmpMsgP)->returnCode;
 }
 
-rootpaerror_t allocateResponseBuffer(CmpMessage* responseP, uint8_t* wsmP )
+rootpaerror_t allocateResponseBuffer(CmpMessage* responseP, CMTHANDLE handle )
 {
     uint32_t elementIndex=1;
     uint32_t offset=0;
-    
-    getRspElementInfo(&elementIndex, wsmP, &offset, &(responseP->length));
 
-    if(0==responseP->length)
+    if(!getRspElementInfo(&elementIndex, handle, &offset, &(responseP->length)))
     {
         return ROOTPA_ERROR_INTERNAL;
     }
@@ -184,13 +182,13 @@
 }
 
 
-rootpaerror_t addTltContainer(uint32_t* indexP, uint32_t* offsetP, const mcUuid_t* uuidP, CMTHANDLE handle, mcResult_t* mcRetP)
+rootpaerror_t addTltContainer(uint32_t* indexP, uint32_t* offsetP, const mcUuid_t* uuidP, mcSpid_t spid, CMTHANDLE handle, mcResult_t* mcRetP)
 {
     rootpaerror_t ret=ROOTPA_ERROR_OUT_OF_MEMORY;
     TLTCONTAINERP tltP = NULL;
     uint32_t contSize=0;
     
-    if((*mcRetP=regReadTlt(uuidP, &tltP, &contSize))==MC_DRV_OK)
+    if((*mcRetP=regReadTlt(uuidP, &tltP, &contSize, spid))==MC_DRV_OK)
     {
         if(ensureMappedBufferSize(handle, (*offsetP) + contSize))
         {        
@@ -297,15 +295,17 @@
         case MC_CMP_CMD_TLT_CONT_ACTIVATE:
             spid_=((cmpCmdTltContActivate_t*)outCommandP)->cmd.sdata.spid;
             memcpy(&tltUuid_,&((cmpCmdTltContActivate_t*)outCommandP)->cmd.sdata.uuid, sizeof(mcUuid_t));
-            ret=addTltContainer(&elementIndex, &offset, &tltUuid_, handle, &mcRet);             
+            ret=addTltContainer(&elementIndex, &offset, &tltUuid_, spid_, handle, &mcRet);             
             break;
         case MC_CMP_CMD_TLT_CONT_LOCK_BY_SP:
             spid_=((cmpCmdTltContLockBySp_t*)outCommandP)->cmd.sdata.spid;
             memcpy(&tltUuid_,&((cmpCmdTltContLockBySp_t*)outCommandP)->cmd.sdata.uuid, sizeof(mcUuid_t));
-            ret=addTltContainer(&elementIndex, &offset, &tltUuid_, handle, &mcRet);
+            ret=addTltContainer(&elementIndex, &offset, &tltUuid_, spid_, handle, &mcRet);
             break;
         case MC_CMP_CMD_TLT_CONT_PERSONALIZE:
-            ret=addTltContainer(&elementIndex, &offset, &((cmpCmdTltContPersonalize_t*)outCommandP)->cmd.sdata.uuid, handle, &mcRet);
+            ret=addTltContainer(&elementIndex, &offset, &((cmpCmdTltContPersonalize_t*)outCommandP)->cmd.sdata.uuid, 
+                                                        ((cmpCmdTltContPersonalize_t*)outCommandP)->cmd.sdata.spid,
+                                                        handle, &mcRet);
             break;
         case MC_CMP_CMD_TLT_CONT_REGISTER:
             spid_=((cmpCmdTltContRegister_t*)outCommandP)->cmd.sdata.spid;
@@ -318,7 +318,7 @@
         case MC_CMP_CMD_TLT_CONT_UNLOCK_BY_SP:
             spid_=((cmpCmdTltContUnlockBySp_t*)outCommandP)->cmd.sdata.spid;
             memcpy(&tltUuid_,&((cmpCmdTltContUnlockBySp_t*)outCommandP)->cmd.sdata.uuid, sizeof(mcUuid_t));
-            ret=addTltContainer(&elementIndex, &offset, &tltUuid_, handle, &mcRet);
+            ret=addTltContainer(&elementIndex, &offset, &tltUuid_, spid_, handle, &mcRet);
             break;
         case MC_CMP_CMD_TLT_CONT_UNREGISTER:
             spid_=((cmpCmdTltContUnlockBySp_t*)outCommandP)->cmd.sdata.spid;
@@ -345,13 +345,26 @@
     switch(commandId)
     {
         case MC_CMP_CMD_GENERATE_AUTH_TOKEN:
-            getRspElementInfo(&elementIndex, handle->wsmP, &offset, &length);
-            regWriteAuthToken((AUTHTOKENCONTAINERP) (handle->mappedP+offset), length);
+            if(getRspElementInfo(&elementIndex, handle, &offset, &length))
+            {
+                mcRet=regWriteAuthToken((AUTHTOKENCONTAINERP) (handle->mappedP+offset), length);
+            }
+            else
+            {
+                mcRet=-1;
+            }
             break;
 
         case MC_CMP_CMD_ROOT_CONT_REGISTER_ACTIVATE:
-            getRspElementInfo(&elementIndex, handle->wsmP, &offset, &length);
-            mcRet=regWriteRoot((ROOTCONTAINERP) (handle->mappedP+offset), length);
+            if(getRspElementInfo(&elementIndex, handle, &offset, &length))
+            {
+                mcRet=regWriteRoot((ROOTCONTAINERP) (handle->mappedP+offset), length);
+            }
+            else
+            {
+                mcRet=-1;
+            }
+                
             if(MC_DRV_OK==mcRet)
             {
                 mcSoAuthTokenCont_t* authTokenP=NULL;
@@ -387,14 +400,18 @@
 
         case MC_CMP_CMD_ROOT_CONT_LOCK_BY_ROOT:
         case MC_CMP_CMD_ROOT_CONT_UNLOCK_BY_ROOT:
-            getRspElementInfo(&elementIndex, handle->wsmP, &offset, &length);
-            mcRet=regWriteRoot((ROOTCONTAINERP) (handle->mappedP+offset), length);
+            if(getRspElementInfo(&elementIndex, handle, &offset, &length))
+            {
+                mcRet=regWriteRoot((ROOTCONTAINERP) (handle->mappedP+offset), length);
+            }
+            else
+            {
+                mcRet=-1;
+            }
+
             break;
 
         case MC_CMP_CMD_ROOT_CONT_UNREGISTER: 
-
-        // TODO-future: check if we should also restore the authtoken here
-
             mcRet=regCleanupRoot();
             break;
 
@@ -403,8 +420,15 @@
         case MC_CMP_CMD_SP_CONT_ACTIVATE:
         case MC_CMP_CMD_SP_CONT_LOCK_BY_ROOT:
         case MC_CMP_CMD_SP_CONT_LOCK_BY_SP:
-            getRspElementInfo(&elementIndex, handle->wsmP, &offset, &length);
-            mcRet=regWriteSp(spid_, (SPCONTAINERP) (handle->mappedP+offset), length);
+            if(getRspElementInfo(&elementIndex, handle, &offset, &length))
+            {
+                mcRet=regWriteSp(spid_, (SPCONTAINERP) (handle->mappedP+offset), length);
+            }
+            else
+            {
+                mcRet=-1;
+            }
+            
             break;
 
         case MC_CMP_CMD_SP_CONT_REGISTER:
@@ -414,11 +438,23 @@
             // we write it last since if SP container writing fails we do not want 
             // to write root container
             uint32_t rootLength=0;
-            getRspElementInfo(&elementIndex, handle->wsmP, &offset, &rootLength); 
-            ROOTCONTAINERP rootP=(ROOTCONTAINERP) (handle->mappedP+offset);
-            
-            getRspElementInfo(&elementIndex, handle->wsmP, &offset, &length);
-            mcRet=regWriteSp(spid_, (SPCONTAINERP) (handle->mappedP+offset), length);
+            ROOTCONTAINERP rootP=NULL;
+            if(getRspElementInfo(&elementIndex, handle, &offset, &rootLength))
+            {
+                rootP=(ROOTCONTAINERP) (handle->mappedP+offset);
+                if(getRspElementInfo(&elementIndex, handle, &offset, &length))
+                {
+                    mcRet=regWriteSp(spid_, (SPCONTAINERP) (handle->mappedP+offset), length);
+                }
+                else    
+                {
+                    mcRet=-1;
+                }
+            }
+            else
+            {
+                mcRet=-1;
+            }
 
             if(MC_DRV_OK==mcRet)
             {
@@ -435,8 +471,14 @@
             mcRet=regCleanupSp(spid_);
             if(MC_DRV_OK==mcRet)
             {
-                getRspElementInfo(&elementIndex, handle->wsmP, &offset, &length);
-                mcRet=regWriteRoot((ROOTCONTAINERP) (handle->mappedP+offset), length);
+                if(getRspElementInfo(&elementIndex, handle, &offset, &length))
+                {
+                    mcRet=regWriteRoot((ROOTCONTAINERP) (handle->mappedP+offset), length);
+                }
+                else    
+                {
+                    mcRet=-1;
+                }                
             }
             else
             {
@@ -452,19 +494,31 @@
             // we write it last since if TLT container writing fails we do not want 
             // to write SP container
             uint32_t spLength=0;
-            getRspElementInfo(&elementIndex, handle->wsmP, &offset, &spLength);
-            SPCONTAINERP spP=(SPCONTAINERP) (handle->mappedP+offset);
+            SPCONTAINERP spP=NULL;
+            if(getRspElementInfo(&elementIndex, handle, &offset, &spLength))
+            {
+                spP=(SPCONTAINERP) (handle->mappedP+offset);
+                if(getRspElementInfo(&elementIndex, handle, &offset, &length))
+                {
+                    mcRet=regWriteTlt(&tltUuid_,(TLTCONTAINERP) (handle->mappedP+offset), length, spid_);
+                }
+                else    
+                {
+                    mcRet=-1;
+                }
+            }
+            else    
+            {
+                mcRet=-1;
+            }
             
-            getRspElementInfo(&elementIndex, handle->wsmP, &offset, &length);
-            mcRet=regWriteTlt(&tltUuid_,(TLTCONTAINERP) (handle->mappedP+offset), length);
-
             if(MC_DRV_OK==mcRet)
             {
                 mcRet=regWriteSp(spid_, spP, spLength);
                 if(MC_DRV_OK!=mcRet)
                 {
                     LOGE("pacmp3 storeContainers for %d regWriteSp failed %d", commandId, mcRet);                                
-                    regCleanupTlt(&tltUuid_);
+                    regCleanupTlt(&tltUuid_, spid_);
                 }
             }
             else
@@ -477,16 +531,30 @@
         case MC_CMP_CMD_TLT_CONT_ACTIVATE:
         case MC_CMP_CMD_TLT_CONT_LOCK_BY_SP:
         case MC_CMP_CMD_TLT_CONT_UNLOCK_BY_SP:
-            getRspElementInfo(&elementIndex, handle->wsmP, &offset, &length);
-            mcRet=regWriteTlt(&tltUuid_,(TLTCONTAINERP) (handle->mappedP+offset), length);
+            if(getRspElementInfo(&elementIndex, handle, &offset, &length))
+            {
+                mcRet=regWriteTlt(&tltUuid_,(TLTCONTAINERP) (handle->mappedP+offset), length, spid_);
+            }
+            else    
+            {
+                mcRet=-1;
+            }
+                
             break;
 
         case MC_CMP_CMD_TLT_CONT_UNREGISTER:
-            mcRet=regCleanupTlt(&tltUuid_);
+            mcRet=regCleanupTlt(&tltUuid_, spid_);
             if(MC_DRV_OK==mcRet)
             {
-                getRspElementInfo(&elementIndex, handle->wsmP, &offset, &length);
-                mcRet=regWriteSp(spid_, (SPCONTAINERP) (handle->mappedP+offset), length);
+                if(getRspElementInfo(&elementIndex, handle, &offset, &length))
+                {
+                    mcRet=regWriteSp(spid_, (SPCONTAINERP) (handle->mappedP+offset), length);
+                }
+                else    
+                {
+                    mcRet=-1;
+                }
+                    
                 break;
             }
             else
@@ -524,12 +592,18 @@
     uint32_t offset=0;
     uint32_t length=0;
 
-    ret=allocateResponseBuffer(outResponseP, handle->wsmP);
+    ret=allocateResponseBuffer(outResponseP, handle);
 
     if(ROOTPA_OK==ret)
     {
-        getRspElementInfo(&elementIndex, handle->wsmP, &offset, &length);
-        memcpy(outResponseP->contentP, handle->mappedP+offset, length );
+        if(getRspElementInfo(&elementIndex, handle, &offset, &length))
+        {
+            memcpy(outResponseP->contentP, handle->mappedP+offset, length );
+        }
+        else
+        {
+            return ROOTPA_ERROR_INTERNAL;
+        }
 
         if (getCmpReturnCode(handle->mappedP)!=SUCCESSFUL) // this checking is here since we want the response to be returned even in case of CMP error
         {
@@ -550,7 +624,14 @@
     if(mcRet != MC_DRV_OK)
     {
         LOGE("pacmp3 handleResponse for %d registry failed %d", commandId, mcRet);                
-        ret = ROOTPA_ERROR_REGISTRY;
+        if(-1==mcRet)
+        {
+            ret = ROOTPA_ERROR_INTERNAL;
+        }
+        else
+        {
+            ret = ROOTPA_ERROR_REGISTRY;
+        }
         if(0==outResponseP->hdr.intRet)
         {
             outResponseP->hdr.intRet=mcRet;
diff --git a/rootpa/Code/Common/pacmtl.c b/rootpa/Code/Common/pacmtl.c
index 5a81e47..1cbfbcb 100755
--- a/rootpa/Code/Common/pacmtl.c
+++ b/rootpa/Code/Common/pacmtl.c
@@ -77,35 +77,53 @@
     ((cmpCommandHeaderTci_t*)wsmP)->commandId=commandId;    
 }
 
-void getRspElementInfo(uint32_t* elementNbrP, uint8_t* wsmP, uint32_t* elementOffsetP, uint32_t* elementLengthP)
+bool getRspElementInfo(uint32_t* elementNbrP, CMTHANDLE handle, uint32_t* elementOffsetP, uint32_t* elementLengthP)
 {
+    uint8_t* wsmP=NULL;
+    cmpMapOffsetInfo_t* elementP=NULL;
+    
+    if(NULL==handle)
+    {
+        LOGE("pacmtl setCmdElementInfo ho handle");
+        *elementLengthP=0;        
+        return false;
+    }
+    wsmP=handle->wsmP;
     LOGD(">>pacmtl getRspElementInfo %x %x %d %d %d %d", ((cmpResponseHeaderTci_t*)wsmP)->version, 
                                                          ((cmpResponseHeaderTci_t*)wsmP)->responseId, 
                                                          ((cmpResponseHeaderTci_t*)wsmP)->len, 
                                                          *((uint32_t*)(wsmP+12)), 
                                                          *((uint32_t*)(wsmP+16)),                                                   
                                                          *((uint32_t*)(wsmP+20)));
-    if(NULL==elementNbrP || NULL == elementOffsetP || NULL == elementLengthP || NULL == wsmP)
+    if(NULL==elementNbrP || NULL == elementOffsetP || NULL == elementLengthP || NULL == handle->wsmP)
     {
-        LOGE("pacmtl setCmdElementInfo NULL's in input, not setting the element %ld %ld", (long int) elementNbrP, (long int) elementOffsetP);
-        return;
+        LOGE("pacmtl getRspElementInfo NULL's in input, not setting the element %ld %ld", (long int) elementNbrP, (long int) elementOffsetP);
+        return false;
     }
 
 
     if(ILLEGAL_ELEMENT==*elementNbrP)
     {
-        LOGE("pacmtl getRspElementInfo error in input, not getting the element %d", *elementNbrP);
+        LOGE("pacmtl getRspElementInfo error in input (illegal element), not getting the element %d", *elementNbrP);
         *elementLengthP=0;
-        return;    
+        return false;
     }
-
-    cmpMapOffsetInfo_t* elementP=(cmpMapOffsetInfo_t*)(wsmP+sizeof(cmpResponseHeaderTci_t));
+   
+    elementP=(cmpMapOffsetInfo_t*)(wsmP+sizeof(cmpResponseHeaderTci_t));
     elementP+=((*elementNbrP)-1);
+
+    if(elementP->offset+elementP->len > handle->mappedSize)
+    {
+        LOGE("pacmtl getRspElementInfo error in input (offset+len too big), not getting the element %d", *elementNbrP);
+        *elementLengthP=0;
+        return false;
+    }
     
     *elementOffsetP=elementP->offset;
     *elementLengthP=elementP->len;
     LOGD("<<pacmtl getRspElementInfo element %d offset %d length %d", *elementNbrP, *elementOffsetP, *elementLengthP);
     (*elementNbrP)++;  // returning number of next element
+    return true;
 }
 
 uint32_t getRspCmpVersion(const uint8_t* wsmP)
diff --git a/rootpa/Code/Common/pacmtl.h b/rootpa/Code/Common/pacmtl.h
index 845e9d8..877c185 100755
--- a/rootpa/Code/Common/pacmtl.h
+++ b/rootpa/Code/Common/pacmtl.h
@@ -34,6 +34,7 @@
 
 #include <MobiCoreDriverApi.h>
 #include <TlCm/3.0/tlCmApi.h>
+#include "trustletchannel.h"
 #include "rootpa.h"
 
 #define CMP_VERSION 0x00030000
@@ -52,7 +53,7 @@
 
 void setCmdCmpVersionAndCmdId(uint8_t* wsmP, cmpCommandId_t commandId);
 
-void getRspElementInfo(uint32_t* elementNbrP, uint8_t* wsmP, uint32_t* elementOffsetP, uint32_t* elementLengthP);
+bool getRspElementInfo(uint32_t* elementNbrP, CMTHANDLE handle, uint32_t* elementOffsetP, uint32_t* elementLengthP);
 
 uint32_t getRspCmpVersion(const uint8_t* wsmP);
 
diff --git a/rootpa/Code/Common/provisioningengine.c b/rootpa/Code/Common/provisioningengine.c
index d1073d6..f09926e 100755
--- a/rootpa/Code/Common/provisioningengine.c
+++ b/rootpa/Code/Common/provisioningengine.c
@@ -44,8 +44,8 @@
 
 
 
-// static const char* const SE_URL="https://se.cgbe.trustonic.com:8443/"; // note that there has to be slash at the end since we are adding suid to it next
-static const char* const SE_URL="http://se.cgbe.trustonic.com:8080/"; // note that there has to be slash at the end since we are adding suid to it next
+static const char* const SE_URL="https://se.cgbe.trustonic.com:8443/"; // note that there has to be slash at the end since we are adding suid to it next
+//static const char* const SE_URL="http://se.cgbe.trustonic.com:8080/"; // note that there has to be slash at the end since we are adding suid to it next
 
 static const char* const RELATION_SELF  =      "relation/self";
 static const char* const RELATION_SYSTEMINFO = "relation/system_info";
@@ -85,7 +85,7 @@
     memset(intInString, 0, 10);
     sprintf(intInString, "/%d", addThis);
     strcpy((uriP+strlen(uriP)), intInString);
-    LOGD("add int to URI %s %d", uriP, addThis);
+    LOGD("add int to URI %s %d", uriP, addThis);   
 }
 
 void cleanup(char** linkP, char** relP, char** commandP)
@@ -143,6 +143,8 @@
     LOGD(">>doProvisioningWithSe");
     callbackP_=callbackP;
     rootpaerror_t ret=ROOTPA_OK;
+    rootpaerror_t tmpRet=ROOTPA_OK;
+    
     if(NULL==callbackP)
     {
         LOGE("No callbackP, can not respond to caller, this should not happen!");
@@ -151,8 +153,11 @@
     if(empty(initialUrl_))
     {
         memset(initialUrl_, 0, INITIAL_URL_BUFFER_LENGTH);
-        memcpy(initialUrl_, &SE_URL, strlen(SE_URL));
+        strncpy(initialUrl_, SE_URL, strlen(SE_URL));
+        
     }
+    
+    
     size_t urlLength=strlen(initialUrl_) + (sizeof(mcSuid_t)*2) + (sizeof(mcSpid_t)*2)+1;
 
     char* tmplinkP=malloc(urlLength);
@@ -206,10 +211,10 @@
     
     while(workToDo)
     {
-        LOGD("in loop link: %s\nrel: %s\nc: command: %s\nresponse: %s\n", (linkP==NULL)?"null":linkP, 
-                                                                             (relP==NULL)?"null":relP, 
-                                                                             (commandP==NULL)?"null":commandP, 
-                                                                             (responseP==NULL)?"null":responseP);
+        LOGD("in loop link: %s\nrel: %s\ncommand: %s\nresponse: %s\n", (linkP==NULL)?"null":linkP, 
+                                                                       (relP==NULL)?"null":relP, 
+                                                                       (commandP==NULL)?"null":commandP, 
+                                                                       (responseP==NULL)?"null":responseP);
     
         if(NULL==relP)
         {
@@ -243,25 +248,15 @@
                 int mcVersionTag=0;
                 mcVersionInfo_t mcVersion;
 
-                ret=getSysInfoP(&osSpecificInfo);
-                if(ret!=ROOTPA_OK)
-                { 
-                    LOGE("getSysInfoP returned an error %d", ret);
-                    callbackP(ERROR, ret, NULL);  // informing SP.PA on problems but continuing anyway 
-                                            // to provide information to SE
-                                                           
-                }
-                ret=getVersionP(&mcVersionTag, &mcVersion);
-                if(ret!=ROOTPA_OK)
-                { 
-                    LOGE("getVersionP returned an error %d", ret);
-                    callbackP(ERROR, ret, NULL);  // informing SP.PA on problems but continuing anyway 
-                                            // to provide information to SE
-                                            
-                }
-                                                                           
-                ret=buildXmlSystemInfo(&responseP, mcVersionTag, &mcVersion, &osSpecificInfo);
+                tmpRet=getSysInfoP(&osSpecificInfo);
+                if(tmpRet!=ROOTPA_OK) ret=tmpRet;                
 
+                tmpRet=getVersionP(&mcVersionTag, &mcVersion);
+                if(tmpRet!=ROOTPA_OK) ret=tmpRet;
+                
+                tmpRet=buildXmlSystemInfo(&responseP, mcVersionTag, &mcVersion, &osSpecificInfo);
+                if(tmpRet!=ROOTPA_OK) ret=tmpRet;
+                
                 free(osSpecificInfo.imeiEsnP);
                 free(osSpecificInfo.mnoP);
                 free(osSpecificInfo.brandP);
@@ -269,14 +264,12 @@
                 free(osSpecificInfo.hardwareP);
                 free(osSpecificInfo.modelP);
                 free(osSpecificInfo.versionP);
-                
-                if(ret!=ROOTPA_OK) callbackP(ERROR, ret, NULL);  // informing SP.PA on problems but continuing anyway 
-                                                           // to provide information to SE
-                
-                ret=httpPutAndReceiveCommand(responseP, &linkP, &relP, &commandP);
+
+                tmpRet=httpPutAndReceiveCommand(responseP, &linkP, &relP, &commandP);
+                if(tmpRet!=ROOTPA_OK) ret=tmpRet;
                 if(ret!=ROOTPA_OK)
                 {
-                    LOGE("httpPutAndReceiveCommand returned an error %d", ret);
+                    LOGE("getSysInfoP, getVersionP or buildXmlSystemInfo or httpPutAndReceiveCommand returned an error %d", ret);
                     callbackP(ERROR, ret, NULL);
                     workToDo=false;
                 }
@@ -311,10 +304,6 @@
                 ret=handleXmlMessage(commandP, &responseP);
                 setCallbackP(NULL);
 
-                if(ret!=ROOTPA_OK) callbackP(ERROR, ret, NULL);  // informing SP.PA on problems but continuing anyway 
-                                                           // to provide information to SE
-
-
                 if(NULL==responseP)
                 {
                     if(ROOTPA_OK==ret) ret=ROOTPA_ERROR_XML;  
@@ -322,7 +311,8 @@
                 }
                 else
                 {
-                    ret=httpPostAndReceiveCommand(responseP, &linkP, &relP, &commandP);
+                    tmpRet=httpPostAndReceiveCommand(responseP, &linkP, &relP, &commandP);
+                    if(tmpRet!=ROOTPA_OK) ret=tmpRet;
                 }
                 
                 if(ret!=ROOTPA_OK)
diff --git a/rootpa/Code/Common/registry.c b/rootpa/Code/Common/registry.c
index 09845ac..471e999 100755
--- a/rootpa/Code/Common/registry.c
+++ b/rootpa/Code/Common/registry.c
@@ -112,20 +112,20 @@
 
 // tlt
 
-int regReadTlt(const mcUuid_t* uuidP, TLTCONTAINERP* tltP, uint32_t* containerSize)
+int regReadTlt(const mcUuid_t* uuidP, TLTCONTAINERP* tltP, uint32_t* containerSize, mcSpid_t spid)
 {
     *containerSize = CONTAINER_BUFFER_SIZE; // this will be update to actual size with the registry call    
     *tltP=malloc(CONTAINER_BUFFER_SIZE);
     if(NULL==*tltP) return MC_DRV_ERR_NO_FREE_MEMORY;
-    return mcRegistryReadTrustletCon(uuidP, *tltP, containerSize);
+    return mcRegistryReadTrustletCon(uuidP, spid, *tltP, containerSize);
 }
 
-int regWriteTlt(const mcUuid_t* uuidP, const TLTCONTAINERP tltP, uint32_t containerSize)
+int regWriteTlt(const mcUuid_t* uuidP, const TLTCONTAINERP tltP, uint32_t containerSize, mcSpid_t spid)
 {
-    return mcRegistryStoreTrustletCon(uuidP, tltP, containerSize);
+    return mcRegistryStoreTrustletCon(uuidP, spid, tltP, containerSize);
 }
 
-int regCleanupTlt(const mcUuid_t* uuidP)
+int regCleanupTlt(const mcUuid_t* uuidP, mcSpid_t spid)
 {
-    return mcRegistryCleanupTrustlet(uuidP);
+    return mcRegistryCleanupTrustlet(uuidP, spid);
 }
diff --git a/rootpa/Code/Common/registry.h b/rootpa/Code/Common/registry.h
index b7cd9ec..093d90f 100755
--- a/rootpa/Code/Common/registry.h
+++ b/rootpa/Code/Common/registry.h
@@ -59,6 +59,6 @@
 
 int regGetSpState(mcSpid_t spid, mcContainerState_t* stateP);
 
-int regReadTlt(const mcUuid_t* uuidP, TLTCONTAINERP* tltP, uint32_t* containerSize);
-int regWriteTlt(const mcUuid_t* uuidP, const TLTCONTAINERP tltP, uint32_t containerSize);
-int regCleanupTlt(const mcUuid_t* uuidP);
+int regReadTlt(const mcUuid_t* uuidP, TLTCONTAINERP* tltP, uint32_t* containerSize, mcSpid_t spid);
+int regWriteTlt(const mcUuid_t* uuidP, const TLTCONTAINERP tltP, uint32_t containerSize, mcSpid_t spid);
+int regCleanupTlt(const mcUuid_t* uuidP, mcSpid_t spid);
diff --git a/rootpa/Code/Common/seclient.c b/rootpa/Code/Common/seclient.c
index 99c0bf5..86fb9bc 100755
--- a/rootpa/Code/Common/seclient.c
+++ b/rootpa/Code/Common/seclient.c
@@ -32,12 +32,14 @@
 #include <string.h>
 #include <stdlib.h>
 #include <stdbool.h>
+#include <time.h>
 
 #include <curl/curl.h>
 
 #include "logging.h"
 #include "rootpaErrors.h"
 #include "seclient.h"
+#include "cacerts.h"
 
 #define HTTP_CODE_MOVED                 301
 #define HTTP_CODE_BAD_REQUEST           400
@@ -46,6 +48,18 @@
 #define HTTP_CODE_REQUEST_TIMEOUT       408
 #define HTTP_CODE_CONFLICT              409
 
+#ifdef __DEBUG
+#define NONEXISTENT_TEST_URL "http://10.255.255.8:9/"
+#endif
+
+#define CERT_PATH_MAX_LEN 256
+#define CECERT_FILENAME "cacert.pem"
+static char certificatePath_[CERT_PATH_MAX_LEN];
+static char certificateFilePath_[CERT_PATH_MAX_LEN];
+
+static int MAX_ATTEMPTS=30;  
+static const struct timespec SLEEPTIME={0,300*1000*1000}; // 0.3 seconds  --> 30x0.3 = 9 seconds
+
 rootpaerror_t httpCommunicate(const char* const inputP, const char** linkP, const char** relP, const char** commandP, httpMethod_t method);
 
 rootpaerror_t httpPostAndReceiveCommand(const char* const inputP, const char** linkP, const char** relP, const char** commandP)
@@ -148,6 +162,25 @@
     return realsize;
 }
  
+#ifdef __DEBUG
+int debug_function (CURL * curl_handle, curl_infotype info, char* debugMessageP, size_t debugMessageSize, void * extrabufferP)
+{
+    if(debugMessageP!=NULL && debugMessageSize!=0)
+    {
+        char* msgP=malloc(debugMessageSize+1);
+        memcpy(msgP, debugMessageP, debugMessageSize);
+        msgP[debugMessageSize]=0;
+        LOGD("curl: %d %s",info, msgP);
+        free(msgP);
+    }
+    else
+    {
+        LOGD("curl: no debug msg %d %d", info, debugMessageSize);
+    }
+    return 0;
+}
+#endif
+
 bool copyHeader(void *contents, size_t length, char** headerP)
 {
     *headerP = malloc(length + 1);
@@ -229,34 +262,75 @@
     return realSize;
 }
 
+uint32_t shorter(uint32_t first, uint32_t second)
+{
+    return (first>second?second:first);
+}
+
+void setCertPath(const char* localPathP, const char* certPathP)
+{
+    memset(certificatePath_, 0, CERT_PATH_MAX_LEN);
+    memset(certificateFilePath_, 0, CERT_PATH_MAX_LEN);
+    
+    if (certPathP!=NULL && (strlen(certPathP)+1)<CERT_PATH_MAX_LEN) 
+    {
+        strcpy(certificatePath_, certPathP);
+    }
+    
+    if (localPathP!=NULL && (strlen(localPathP)+1+sizeof(CECERT_FILENAME))<CERT_PATH_MAX_LEN) 
+    {
+        strcpy(certificateFilePath_, localPathP);
+        strcat(certificateFilePath_, "/");
+    }
+    strcat(certificateFilePath_, CECERT_FILENAME);
+}
+//
+// TODO-refactor: saveCertFile is duplicate from saveFile in xmlMessageHandler.c, move these to common place
+//
+void saveCertFile(char* filePath, char* fileContent)
+{
+    LOGD(">>saveCertFile %s", filePath);
+    FILE* fh;
+    if ((fh = fopen(filePath, "w")) != NULL) // recreating the file every time, this is not the most efficient way, but ensures 
+	{                                        // the file is updated in case rootpa and the required content is updated
+        fprintf(fh, "%s", fileContent);
+        fclose(fh);
+	}
+    else
+    {
+        LOGE("saveCertFile no handle %s", filePath);
+    }
+    LOGD("<<saveCertFile");
+}
+
 bool setBasicOpt(CURL* curl_handle, MemoryStruct* chunkP, HeaderStruct* headerChunkP, const char* linkP)
 {
-    if(curl_easy_setopt(curl_handle, CURLOPT_URL, linkP)!=0)
+    if(curl_easy_setopt(curl_handle, CURLOPT_URL, linkP)!=CURLE_OK)
     {
         LOGE("curl_easy_setopt CURLOPT_URL failed");
         return false;
     }
     
     /* reading response to memory instead of file */
-    if(curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, writeMemoryCallback)!=0)
+    if(curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, writeMemoryCallback)!=CURLE_OK)
     {
         LOGE("curl_easy_setopt CURLOPT_WRITEFUNCTION failed");
         return false;
     }
     
-    if(curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, writeHeaderCallback)!=0)
+    if(curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, writeHeaderCallback)!=CURLE_OK)
     {
         LOGE("curl_easy_setopt CURLOPT_HEADERFUNCTION failed");
         return false;
     }
 
-    if(curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *) chunkP)!=0)
+    if(curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *) chunkP)!=CURLE_OK)
     {
         LOGE("curl_easy_setopt CURLOPT_WRITEDATA failed");
         return false;
     }
 
-    if(curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, (void *) headerChunkP)!=0)
+    if(curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, (void *) headerChunkP)!=CURLE_OK)
     {
         LOGE("curl_easy_setopt CURLOPT_WRITEHEADER failed");
         return false;
@@ -265,66 +339,98 @@
      
     /* some servers don't like requests that are made without a user-agent
        field, so we provide one */ 
-    if(curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "rpa/1.0")!=0)
+    if(curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "rpa/1.0")!=CURLE_OK)
     {
         LOGE("curl_easy_setopt CURLOPT_USERAGENT failed");
         return false;
     }
 
-    if(curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1L)!=0)
+    if(curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1L)!=CURLE_OK)
     {
         LOGE("curl_easy_setopt CURLOPT_USERAGENT failed");
         return false;
     }
 
-    if(curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 120L)!=0)  // timeout after 120 seconds
+
+    saveCertFile(certificateFilePath_, CA_CERTIFICATES);
+    
+    LOGD("curl_easy_setopt CURLOPT_CAINFO %s", certificateFilePath_);
+    if(curl_easy_setopt(curl_handle, CURLOPT_CAINFO,  certificateFilePath_)!=CURLE_OK)
+    {
+        LOGE("curl_easy_setopt CURLOPT_CAINFO failed");
+        return false;
+    }
+
+    LOGD("curl_easy_setopt CURLOPT_CAPATH %s", certificatePath_);
+    if(curl_easy_setopt(curl_handle, CURLOPT_CAPATH,  certificatePath_)!=CURLE_OK)
+    {
+        LOGE("curl_easy_setopt CURLOPT_CAPATH failed");
+        return false;
+    }   
+
+    long int se_connection_timeout=120L; // timeout after 120 seconds
+#ifdef __DEBUG
+    curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L);
+    curl_easy_setopt(curl_handle, CURLOPT_DEBUGFUNCTION, debug_function);   
+    
+    if(strncmp(linkP, NONEXISTENT_TEST_URL, shorter(strlen(NONEXISTENT_TEST_URL), strlen(linkP)))==0)
+    {
+        se_connection_timeout=3L; // reducing the connection timeout for testing purposes
+        MAX_ATTEMPTS=1; // this is for testint code, we are using nonexitent url here so no unncessary attempts
+        LOGD("setBasicOpt timeout set to %ld", se_connection_timeout);
+    }   
+#endif
+
+    if(curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, se_connection_timeout)!=CURLE_OK)
     {
         LOGE("curl_easy_setopt CURLOPT_TIMEOUT failed");
         return false;
     }
 
+/** libcurl uses the http_proxy and https_proxy environment variables for proxy settings.
+    That variable is set in the OS specific wrapper. These are left here in order to make 
+    this comment earier to be found in searches.
 
-// TODO-RELEASE, hopefully these are not needed but libcurl can use the environment variable settings.
-// if they are needed, the settings need to be obtained from the database
-// also disablingCURLOPT_SSL_VERIFYPEER is for testing purposes only
-//
-//    curl_easy_setopt(curl_handle,CURLOPT_PROXY, "http://web-proxy.intern:3128");
-//    curl_easy_setopt(curl_handle,CURLOPT_PROXYUSERNAME, "soukkote");
-//    curl_easy_setopt(curl_handle,CURLOPT_PROXYPASSWORD, "");
-//    curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L);
-
+    curl_easy_setopt(curl_handle,CURLOPT_PROXY, "http://proxyaddress");
+    curl_easy_setopt(curl_handle,CURLOPT_PROXYPORT, "read_proxy_port");
+    curl_easy_setopt(curl_handle,CURLOPT_PROXYUSERNAME, "read_proxy_username");
+    curl_easy_setopt(curl_handle,CURLOPT_PROXYPASSWORD, "read_proxy_password");
+*/
+    
     return true;
 }
 
+
+
 bool setPutOpt(CURL* curl_handle, ResponseStruct* responseChunk)
 {
     LOGD(">>setPutOpt");
-    if (curl_easy_setopt(curl_handle, CURLOPT_READFUNCTION, readResponseCallback)!=0)
+    if (curl_easy_setopt(curl_handle, CURLOPT_READFUNCTION, readResponseCallback)!=CURLE_OK)
     {
         LOGE("curl_easy_setopt CURLOPT_READFUNCTION failed");
         return false;
     }
 
-    if (curl_easy_setopt(curl_handle, CURLOPT_UPLOAD, 1L)!=0)
+    if (curl_easy_setopt(curl_handle, CURLOPT_UPLOAD, 1L)!=CURLE_OK)
     {
         LOGE("curl_easy_setopt CURLOPT_UPLOAD failed");
         return false;
     }
 
-    if (curl_easy_setopt(curl_handle, CURLOPT_PUT, 1L)!=0)
+    if (curl_easy_setopt(curl_handle, CURLOPT_PUT, 1L)!=CURLE_OK)
     {
         LOGE("curl_easy_setopt CURLOPT_PUT failed");
         return false;
     }
 
-    if (curl_easy_setopt(curl_handle, CURLOPT_READDATA, responseChunk)!=0)
+    if (curl_easy_setopt(curl_handle, CURLOPT_READDATA, responseChunk)!=CURLE_OK)
     {
         LOGE("curl_easy_setopt CURLOPT_READDATA failed");
         return false;
     }
 
     long s=responseChunk->size;
-    if (curl_easy_setopt(curl_handle, CURLOPT_INFILESIZE, s)!=0)
+    if (curl_easy_setopt(curl_handle, CURLOPT_INFILESIZE, s)!=CURLE_OK)
     {
         LOGE("curl_easy_setopt CURLOPT_INFILESIZE_LARGE failed");
         return false;
@@ -334,10 +440,18 @@
     return true;
 }
 
-bool setPostOpt(CURL* curl_handle, const char* inputP)
+bool setPostOpt(CURL* curl_handle, const char* inputP, struct curl_slist* disableChunkP)
 {
-    inputP?(LOGD(">>setPostOpt %d %s", (int) strlen(inputP), inputP)):(LOGD(">>setPostOpt "));
-    if (curl_easy_setopt(curl_handle, CURLOPT_POST, 1L)!=0)
+    if(inputP)
+    {
+        LOGD(">>setPostOpt %d %s", (int) strlen(inputP), inputP);
+    }
+    else
+    {
+        LOGD(">>setPostOpt");
+    }
+    
+    if (curl_easy_setopt(curl_handle, CURLOPT_POST, 1L)!=CURLE_OK)
     {
         LOGE("curl_easy_setopt CURLOPT_POST failed");
         return false;
@@ -345,19 +459,24 @@
 
     if(NULL==inputP) 
     {
-        if (curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, 0L)!=0)
+        if (curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, 0L)!=CURLE_OK)
         {
             LOGE("curl_easy_setopt CURLOPT_POSTFIELDSIZE failed");
             return false;
         }
     }
         
-    if (curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, (void*) inputP)!=0)
+    if (curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, (void*) inputP)!=CURLE_OK)
     {
         LOGE("curl_easy_setopt CURLOPT_POSTFIELDS failed");
         return false;
     }
-    
+
+    if (curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, disableChunkP)!=CURLE_OK)
+    {
+        LOGE("curl_easy_setopt CURLOPT_HTTPHEADER failed");
+        return false;
+    }
     LOGD("<<setPostOpt");
     return true;
 }
@@ -365,7 +484,7 @@
 bool setDeleteOpt(CURL* curl_handle, const char* inputP)
 {
     LOGD(">>setDeleteOpt %s", inputP);
-    if (curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, "DELETE")!=0)
+    if (curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, "DELETE")!=CURLE_OK)
     {
         LOGE("curl_easy_setopt CURLOPT_CUSTOMREQUEST failed");
         return false;
@@ -380,7 +499,7 @@
 
 rootpaerror_t openSeClientAndInit()
 {
-    if(curl_global_init(CURL_GLOBAL_ALL)!=0)
+    if(curl_global_init(CURL_GLOBAL_ALL)!=CURLE_OK)
     {
         LOGE("curl_gloabal_init failed");
         return ROOTPA_ERROR_NETWORK;
@@ -407,6 +526,12 @@
 
 rootpaerror_t httpCommunicate(const char * const inputP, const char** linkP, const char** relP, const char** commandP, httpMethod_t method)
 {
+    rootpaerror_t ret=ROOTPA_OK;
+    long int curlRet=CURLE_COULDNT_CONNECT;
+    long int http_code = 0;
+    int attempts=0;
+    struct curl_slist* disableChunkP = NULL;
+    
     LOGD(">>httpCommunicate");
     if(NULL==linkP || NULL==relP || NULL==commandP || NULL==*linkP)
     {
@@ -450,7 +575,9 @@
 	}
 	else if(method == httpMethod_POST)
 	{
-		if (setPostOpt(curl_handle_, inputP)==false)
+        /* disable Expect: 100-continue since it creates problems with some proxies */ 
+        disableChunkP = curl_slist_append(disableChunkP, "Expect:");
+		if (setPostOpt(curl_handle_, inputP, disableChunkP)==false)
 		{
 			LOGE("setPostOpt failed");
 			free(chunk.memoryP);
@@ -477,7 +604,6 @@
 		}
 	}
 
-
     if(setBasicOpt(curl_handle_, &chunk, &headerChunk, *linkP)==false)
     {
         LOGE("setBasicOpt failed");
@@ -485,19 +611,25 @@
         return ROOTPA_ERROR_NETWORK;    
     }
 
-    rootpaerror_t ret=ROOTPA_OK;
-    ret=curl_easy_perform(curl_handle_);
-    long int http_code = 0;
-    curl_easy_getinfo (curl_handle_, CURLINFO_RESPONSE_CODE, &http_code);
-    if(ret!=0)    
+    while(curlRet!=CURLE_OK && attempts++ < MAX_ATTEMPTS)
     {
-        LOGE("curl_easy_perform failed %d", ret);
+        curlRet=curl_easy_perform(curl_handle_);
+        LOGD("curl_easy_perform %ld %d", curlRet, attempts);
+        if(CURLE_OK==curlRet) break;
+        nanosleep(&SLEEPTIME,NULL);
+    }
+
+    curl_easy_getinfo (curl_handle_, CURLINFO_RESPONSE_CODE, &http_code);
+    if(curlRet!=CURLE_OK)    
+    {
+        LOGE("curl_easy_perform failed %ld", curlRet);
         free(chunk.memoryP);
         free(headerChunk.linkP);
         free(headerChunk.relP);
+        curl_easy_reset(curl_handle_);        
         return ROOTPA_ERROR_NETWORK;
     }
-    
+
     LOGD("http return code from SE %ld", (long int) http_code);    
     if ((200 <= http_code &&  http_code < 300) ||  HTTP_CODE_MOVED == http_code) 
     {
@@ -525,11 +657,12 @@
     *commandP=chunk.memoryP;  // this needs to be freed by client
     *linkP=headerChunk.linkP; // this needs to be freed by client
     *relP=headerChunk.relP;   // this needs to be freed by client
- 
+    if (disableChunkP) curl_slist_free_all(disableChunkP); // since we disabled some headers    
+
     curl_easy_reset(curl_handle_);
     LOGD("%lu bytes retrieved\n", (long)chunk.size);
      
-    LOGD("<<httpCommunicate %ld %ld", (long int) ret, (long int) http_code); 
+    LOGD("<<httpCommunicate %d %ld %ld", (int) ret, (long int) http_code, (long int) curlRet); 
     return ret;
 }
 
diff --git a/rootpa/Code/Common/seclient.h b/rootpa/Code/Common/seclient.h
index bb6f34a..b590891 100755
--- a/rootpa/Code/Common/seclient.h
+++ b/rootpa/Code/Common/seclient.h
@@ -60,4 +60,7 @@
 rootpaerror_t httpPutAndReceiveCommand(const char* const inputP, const char** linkP, const char** relP, const char** commandP);
 rootpaerror_t httpDeleteAndReceiveCommand(const char** linkP, const char** relP, const char** commandP);
 
+void setCertPath(const char* localPathP, const char* certPathP);
+
+
 #endif //SECLIENT_H
diff --git a/rootpa/Code/Common/xmlmessagehandler.c b/rootpa/Code/Common/xmlmessagehandler.c
index 83d9670..312a018 100755
--- a/rootpa/Code/Common/xmlmessagehandler.c
+++ b/rootpa/Code/Common/xmlmessagehandler.c
@@ -45,7 +45,7 @@
 #include "enrollmentservicexmlschema.h"
 #include "xmlmessagehandler.h"
 #include "contentmanager.h"
-#include "provisioningengine.h" //TODO-Tero
+#include "provisioningengine.h"
 #include "base64.h"
 
 #define ENROLLMENT_SERVICE_NS_PREFIX 0 // "mces" 
@@ -114,8 +114,11 @@
         case ROOTPA_ERROR_LOCK:
             return STRING_ROOTPA_ERROR_LOCK;
 
-        case ROOTPA_ERROR_COMMAND_EXECUTION:
-            return STRING_ROOTPA_ERROR_COMMAND_EXECUTION;
+//
+// this is not currently understood by SE
+//
+//        case ROOTPA_ERROR_COMMAND_EXECUTION:
+//            return STRING_ROOTPA_ERROR_COMMAND_EXECUTION;
 
         case ROOTPA_ERROR_REGISTRY:
             return STRING_ROOTPA_ERROR_REGISTRY;
@@ -330,7 +333,12 @@
     {
         LOGE("handleCmpCommand: was not able to realloc");
         // In this case we can not return an error to SE unless we set some of the earlier errors. 
-        // TODO-RELEASE: if ignoreError is false should we free all and set numberOfCmpCommands to 0?
+        if(!ignoreError)
+        {
+            free(*cmpCommandsP);
+            *cmpCommandsP=NULL;
+            numberOfCmpCommands=0;
+        }
     }
     return numberOfCmpCommands;
 }
@@ -384,10 +392,15 @@
 
     if(NULL == tmpCommandsP)
     {
-        LOGE("handleUploadCommand: was not able to realloc, returning");
+        LOGE("handleUploadCommand: was not able to realloc, returning %d", ignoreError);
+        if(!ignoreError)
+        {
+            free(*uploadCommandsP);
+            *uploadCommandsP=NULL;
+            numberOfUploadCommands=0;
+        }
         return numberOfUploadCommands;
         // In this case we can not return an error to SE unless we set some of the earlier errors. 
-        // TODO-RELEASE: if ignoreError is false should we free all and set numberOfUploadCommands to 0?
     }
             
     localCommandsP=tmpCommandsP;
@@ -471,7 +484,8 @@
 {
     LOGD(">>handleCommandAndFillResponse");
     rootpaerror_t ret=ROOTPA_OK;
-
+    rootpaerror_t tmpRet=ROOTPA_OK;
+    
     xmlNodePtr rspRootElementP = xmlDocGetRootElement(xmlResponseP);    
     if(NULL==rspRootElementP) return ROOTPA_ERROR_XML;
    
@@ -497,12 +511,20 @@
             case CMP:
             {   
                 numberOfCmpCommands=extractCmpCommand(&cmpCommandsP, numberOfCmpCommands, id, commandValueP, ignoreError);
+                if(0==numberOfCmpCommands)
+                {
+                    ret=ROOTPA_ERROR_OUT_OF_MEMORY;                    
+                }
                 break;
             }
             case SO_UPLOAD:
             // intentional fallthrough
             case TLT_UPLOAD:
                 numberOfUploadCommands=handleUploadCommand(commandType, &uploadCommandsP, numberOfUploadCommands, id, commandValueP, ignoreError);
+                if(0==numberOfCmpCommands)
+                {
+                    ret=ROOTPA_ERROR_OUT_OF_MEMORY;
+                }                    
                 break;
             default:                
                 LOGE("handleCommandAndFillResponse: received unknown command");
@@ -510,6 +532,8 @@
                 break;
         }
         xmlFree(commandValueP);
+
+        if(ROOTPA_ERROR_OUT_OF_MEMORY == ret) break;
         
         if(commandType != CMP && 
           false == ignoreError && 
@@ -531,14 +555,15 @@
         }
         else
         {
-            ret=executeContentManagementCommands(numberOfCmpCommands, cmpCommandsP, cmpResponsesP, &internalError);
-            if(ROOTPA_OK!=ret)
+            tmpRet=executeContentManagementCommands(numberOfCmpCommands, cmpCommandsP, cmpResponsesP, &internalError);
+            if(ROOTPA_OK!=tmpRet)
             {
-                LOGE("call to executeContentManagementCommands failed with %d, continuing anyway", ret);
+                LOGE("call to executeContentManagementCommands failed with %d, continuing anyway", tmpRet);
                 // return code from executeContentManagementCommands is here more informative than anything else
                 // even in an error case we need to return response to SE, the errors are also included in the 
                 // actual CMP messages.
-            }   
+                ret=tmpRet;
+            }
         }
     }
     
@@ -546,15 +571,17 @@
     if (ret!=ROOTPA_ERROR_OUT_OF_MEMORY)
     {
         xmlNodePtr resultListNodeP=xmlNewChild(rspRootElementP, nameSpace_, BAD_CAST "commandResultList", NULL);
-        ret=handleCmpResponses(numberOfCmpCommands, cmpResponsesP, resultListNodeP); 
-        if(ROOTPA_OK!=ret)
+        tmpRet=handleCmpResponses(numberOfCmpCommands, cmpResponsesP, resultListNodeP); 
+        if(ROOTPA_OK!=tmpRet)
         {
-            LOGE("handleCommandAndFillResponse: not able to handle all Cmp responses, still continuing with UploadResponses %d", ret);
+            LOGE("handleCommandAndFillResponse: not able to handle all Cmp responses, still continuing with UploadResponses %d", tmpRet);
+            ret=tmpRet;
         }      
-        ret=handleUploadResponses(numberOfUploadCommands, uploadCommandsP, resultListNodeP);
-        if(ROOTPA_OK!=ret)
+        tmpRet=handleUploadResponses(numberOfUploadCommands, uploadCommandsP, resultListNodeP);
+        if(ROOTPA_OK!=tmpRet)
         {
-            LOGE("handleCommandAndFillResponse: not able to handle all Upload responses %d", ret);
+            LOGE("handleCommandAndFillResponse: not able to handle all Upload responses %d", tmpRet);
+            ret=tmpRet;
         }      
     }
     // cleanup what has not yet been cleaned
@@ -696,6 +723,7 @@
 {
     LOGD(">>handleXmlMessage");
     rootpaerror_t ret=ROOTPA_OK;
+    rootpaerror_t tmpRet=ROOTPA_OK;    
     *responseP=NULL; 
         
     if (NULL==messageP)
@@ -718,8 +746,9 @@
 
     if(!validXmlMessage(xmlDocP))
     {
-        LOGE("handleXmlMessage, invalid message %s", messageP);
+        LOGE("handleXmlMessage, invalid message %s", messageP); 
         ret=ROOTPA_ERROR_XML;
+        // attempting to parse the message anyway.
     }
 
     xmlDocPtr xmlResponseP=createXmlResponse(ret);
@@ -728,7 +757,8 @@
 
     if(xmlResponseP)
     {
-        ret=handleCommandAndFillResponse(xmlDocP, xmlResponseP);
+        tmpRet=handleCommandAndFillResponse(xmlDocP, xmlResponseP);
+        if(tmpRet!=ROOTPA_OK) ret=tmpRet;
     }
     else
     {
@@ -937,7 +967,7 @@
     memset(enrollmentServiceFullPath_, 0, XSD_PATH_MAX_LEN);
     memset(platformTypesFullPath_, 0, XSD_PATH_MAX_LEN);
 
-    if (xsdpathP!=NULL && strlen(xsdpathP)<(XSD_PATH_MAX_LEN+1+sizeof(ENROLLMENT_SERVICE_XSD_NAME))) // ENROLLMENT_SERVICE_XSD_NAME is the longer of the two
+    if (xsdpathP!=NULL && strlen(xsdpathP)+1+sizeof(ENROLLMENT_SERVICE_XSD_NAME)<XSD_PATH_MAX_LEN) // ENROLLMENT_SERVICE_XSD_NAME is the longer of the two
     {
         strcpy(enrollmentServiceFullPath_, xsdpathP);
         strcpy(platformTypesFullPath_, xsdpathP);
diff --git a/rootpa/Test/Android/RootPAClient/AndroidManifest.xml b/rootpa/Test/Android/RootPAClient/AndroidManifest.xml
index 648924c..9a912b1 100755
--- a/rootpa/Test/Android/RootPAClient/AndroidManifest.xml
+++ b/rootpa/Test/Android/RootPAClient/AndroidManifest.xml
@@ -5,13 +5,12 @@
           android:versionCode="1" 
           android:versionName="1.0" >
 
-  <uses-sdk android:minSdkVersion="8"
-            android:targetSdkVersion="16" />
+  <uses-sdk android:minSdkVersion="14"
+            android:targetSdkVersion="17" />
 
-  <uses-permission android:name="android.permission.INTERNET"/>
   <uses-permission android:name="com.gd.mobicore.pa.permission.OEM_PERMISSION"/>
   <uses-permission android:name="com.gd.mobicore.pa.permission.DEVELOPER_PERMISSION" />
-    
+     
   <application 
     android:label="@string/app_name" 
     android:icon="@drawable/icon" 
diff --git a/rootpa/Test/Android/RootPAClient/ant.properties b/rootpa/Test/Android/RootPAClient/ant.properties
index 15b9767..82a6980 100755
--- a/rootpa/Test/Android/RootPAClient/ant.properties
+++ b/rootpa/Test/Android/RootPAClient/ant.properties
@@ -1,3 +1,8 @@
 out.dir=out
 # extra.classpath.value=../../../Code/Android/out/classes/
 java.compilerargs="-Xlint:unchecked"
+
+debug.key.store=../../../Build/google_certificate.keystore
+debug.key.alias=platform
+debug.key.store.password=android
+debug.key.alias.password=android
\ No newline at end of file
diff --git a/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpGenerateAuthTokenNoStore.java b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpGenerateAuthTokenNoStore.java
new file mode 100755
index 0000000..95a2fc1
--- /dev/null
+++ b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpGenerateAuthTokenNoStore.java
@@ -0,0 +1,88 @@
+/*
+Copyright  © Trustonic Limited 2013
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice, this 
+     list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright notice, 
+     this list of conditions and the following disclaimer in the documentation 
+     and/or other materials provided with the distribution.
+
+  3. Neither the name of the Trustonic Limited nor the names of its contributors 
+     may be used to endorse or promote products derived from this software 
+     without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
+OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.gd.mobicore.pa.service.Test;
+
+import java.util.Arrays;
+import android.util.Log;
+import com.gd.mobicore.pa.ifc.CommandResult;
+import com.gd.mobicore.pa.ifc.CmpMsg;
+import com.gd.mobicore.pa.ifc.CmpCommand;
+import com.gd.mobicore.pa.ifc.CmpResponse;
+
+public class CmpGenerateAuthTokenNoStore extends CmpTest{
+    public final static byte[] ANOTHER_SUID={
+        0, 0, 0, 0, (byte) 0x44, (byte) 0x55, (byte) 0x66, (byte) 0x77, (byte) 0x88, (byte) 0x99, 
+        (byte) 0xAA, (byte) 0xBB, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01 };
+
+    public final static int CMD_SUID_INDEX=4;        
+        
+    public CmpGenerateAuthTokenNoStore(){
+        super(CmpMsg.MC_CMP_CMD_GENERATE_AUTH_TOKEN);
+    }
+    
+    public CmpCommand createCommand(){
+        CmpCommand command=new CmpCommand(id_);
+        byte[] ksocauth= new byte[32];
+        int kid=0; 
+        byte[] psssig = new byte[256]; 
+                
+        command.setByteArray(CMD_SUID_INDEX, ANOTHER_SUID);
+        command.setByteArray(28, ksocauth);
+        command.setInt(60,kid);
+        command.setByteArray(64, psssig);
+        return command;
+    }    
+
+
+   public void checkResult(CmpResponse response){
+        super.checkResult(response);
+        if(false==result_) return;
+
+        if(responseSize_>=160){
+            byte[] authToken=response.getByteArray(8, AUTH_TOKEN.length);
+            if(!Arrays.equals(authToken, AUTH_TOKEN)){
+                result_=false;            
+            }
+        }else{
+            result_=false;                
+        }
+        if(result_==false){
+            Log.i(TAG, "Content of Generate Auth Token Response:"+byteArrayToDisplayableString(response.getByteArray(0,responseSize_)));
+        }
+
+        return;
+    }
+
+}
+
+
+
diff --git a/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpGenerateAuthTokenOffsetOut.java b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpGenerateAuthTokenOffsetOut.java
new file mode 100755
index 0000000..9f595e7
--- /dev/null
+++ b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpGenerateAuthTokenOffsetOut.java
@@ -0,0 +1,89 @@
+/*
+Copyright  © Trustonic Limited 2013
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice, this 
+     list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright notice, 
+     this list of conditions and the following disclaimer in the documentation 
+     and/or other materials provided with the distribution.
+
+  3. Neither the name of the Trustonic Limited nor the names of its contributors 
+     may be used to endorse or promote products derived from this software 
+     without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
+OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.gd.mobicore.pa.service.Test;
+
+import java.util.Arrays;
+import android.util.Log;
+import com.gd.mobicore.pa.ifc.CommandResult;
+import com.gd.mobicore.pa.ifc.CmpMsg;
+import com.gd.mobicore.pa.ifc.CmpCommand;
+import com.gd.mobicore.pa.ifc.CmpResponse;
+
+public class CmpGenerateAuthTokenOffsetOut extends CmpTest{
+    public final static byte[] OFFSET_OUT_SUID={
+        0, 0, 0, 0, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x77, (byte) 0x88, (byte) 0x99, 
+        (byte) 0xAA, (byte) 0xBB, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01 };
+
+    public final static int CMD_SUID_INDEX=4;
+
+    public CmpGenerateAuthTokenOffsetOut(){
+        super(CmpMsg.MC_CMP_CMD_GENERATE_AUTH_TOKEN);
+    }
+    
+    public CmpCommand createCommand(){
+        CmpCommand command=new CmpCommand(id_);
+        byte[] ksocauth= new byte[32];
+        int kid=0; 
+        byte[] psssig = new byte[256]; 
+                
+        command.setByteArray(CMD_SUID_INDEX, OFFSET_OUT_SUID);
+        command.setByteArray(28, ksocauth);
+        command.setInt(60,kid);
+        command.setByteArray(64, psssig);
+        return command;
+    }    
+
+
+   public void checkResult(CmpResponse response){
+        super.checkResult(response);
+        if(false==result_) return;
+
+        if(responseSize_>=160){
+            byte[] authToken=response.getByteArray(8, AUTH_TOKEN.length);
+            if(!Arrays.equals(authToken, AUTH_TOKEN)){
+                result_=false;            
+            }
+
+        }else{
+            result_=false;                
+        }
+        if(result_==false){
+            Log.i(TAG, "Content of Generate Auth Token Response:"+byteArrayToDisplayableString(response.getByteArray(0,responseSize_)));
+        }
+
+        return;
+    }
+
+}
+
+
+
diff --git a/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpGenerateAuthTokenOffsetPlusLengthOut.java b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpGenerateAuthTokenOffsetPlusLengthOut.java
new file mode 100755
index 0000000..bc4158e
--- /dev/null
+++ b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpGenerateAuthTokenOffsetPlusLengthOut.java
@@ -0,0 +1,91 @@
+/*
+Copyright  © Trustonic Limited 2013
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice, this 
+     list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright notice, 
+     this list of conditions and the following disclaimer in the documentation 
+     and/or other materials provided with the distribution.
+
+  3. Neither the name of the Trustonic Limited nor the names of its contributors 
+     may be used to endorse or promote products derived from this software 
+     without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
+OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.gd.mobicore.pa.service.Test;
+
+import java.util.Arrays;
+import android.util.Log;
+import com.gd.mobicore.pa.ifc.CommandResult;
+import com.gd.mobicore.pa.ifc.CmpMsg;
+import com.gd.mobicore.pa.ifc.CmpCommand;
+import com.gd.mobicore.pa.ifc.CmpResponse;
+
+public class CmpGenerateAuthTokenOffsetPlusLengthOut extends CmpTest{
+
+    public final static byte[] OFFSET_PLUS_LEN_OUT_SUID={
+        0, 0, 0, 0, (byte) 0x04, (byte) 0x05, (byte) 0x66, (byte) 0x77, (byte) 0x88, (byte) 0x99, 
+        (byte) 0xAA, (byte) 0xBB, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01 };
+
+    public final static int CMD_SUID_INDEX=4;
+
+        
+    public CmpGenerateAuthTokenOffsetPlusLengthOut(){
+        super(CmpMsg.MC_CMP_CMD_GENERATE_AUTH_TOKEN);
+    }
+    
+    public CmpCommand createCommand(){
+        CmpCommand command=new CmpCommand(id_);
+        byte[] ksocauth= new byte[32];
+        int kid=0; 
+        byte[] psssig = new byte[256]; 
+                
+        command.setByteArray(CMD_SUID_INDEX, OFFSET_PLUS_LEN_OUT_SUID);
+        command.setByteArray(28, ksocauth);
+        command.setInt(60,kid);
+        command.setByteArray(64, psssig);
+        return command;
+    }    
+
+
+   public void checkResult(CmpResponse response){
+       result_=true;
+        
+        if(response==null){
+            Log.i(TAG,"response for "+id_+" is null");        
+            result_=false;
+            return;
+        }
+        
+        responseSize_=response.size();
+        Log.i(TAG,"size of "+id_+" response: "+responseSize_);
+
+        if (responseSize_!=0){ 
+            Log.e(TAG,"****NOTE: response size!=0");            
+            result_=false;
+            return;
+        }
+        return;
+    }
+
+}
+
+
+
diff --git a/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpGenerateAuthTokenResponseIdWrong.java b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpGenerateAuthTokenResponseIdWrong.java
new file mode 100755
index 0000000..a9bbed0
--- /dev/null
+++ b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpGenerateAuthTokenResponseIdWrong.java
@@ -0,0 +1,91 @@
+/*
+Copyright  © Trustonic Limited 2013
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice, this 
+     list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright notice, 
+     this list of conditions and the following disclaimer in the documentation 
+     and/or other materials provided with the distribution.
+
+  3. Neither the name of the Trustonic Limited nor the names of its contributors 
+     may be used to endorse or promote products derived from this software 
+     without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
+OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.gd.mobicore.pa.service.Test;
+
+import java.util.Arrays;
+import android.util.Log;
+import com.gd.mobicore.pa.ifc.CommandResult;
+import com.gd.mobicore.pa.ifc.CmpMsg;
+import com.gd.mobicore.pa.ifc.CmpCommand;
+import com.gd.mobicore.pa.ifc.CmpResponse;
+
+public class CmpGenerateAuthTokenResponseIdWrong extends CmpTest{
+
+    public final static byte[] RESPONSE_ID_WRONG_SUID={
+        0, 0, 0, 0, (byte) 0x04, (byte) 0x55, (byte) 0x66, (byte) 0x77, (byte) 0x88, (byte) 0x99, 
+        (byte) 0xAA, (byte) 0xBB, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01 };
+
+    public final static int CMD_SUID_INDEX=4;
+
+    
+    public CmpGenerateAuthTokenResponseIdWrong(){
+        super(CmpMsg.MC_CMP_CMD_GENERATE_AUTH_TOKEN);
+    }
+    
+    public CmpCommand createCommand(){
+        CmpCommand command=new CmpCommand(id_);
+        byte[] ksocauth= new byte[32];
+        int kid=0; 
+        byte[] psssig = new byte[256]; 
+                
+        command.setByteArray(CMD_SUID_INDEX, RESPONSE_ID_WRONG_SUID);
+        command.setByteArray(28, ksocauth);
+        command.setInt(60,kid);
+        command.setByteArray(64, psssig);
+        return command;
+    }    
+
+
+   public void checkResult(CmpResponse response){
+       result_=true;
+        
+        if(response==null){
+            Log.i(TAG,"response for "+id_+" is null");        
+            result_=false;
+            return;
+        }
+        
+        responseSize_=response.size();
+        Log.i(TAG,"size of "+id_+" response: "+responseSize_);
+
+        if (responseSize_!=0){ 
+            Log.e(TAG,"****NOTE: response size!=0");            
+            result_=false;
+            return;
+        }
+        return;
+    }
+
+}
+
+
+
diff --git a/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpTest.java b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpTest.java
index 96bcd12..06b18e0 100755
--- a/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpTest.java
+++ b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpTest.java
@@ -50,7 +50,7 @@
 cases to be executed.
 */
 public class CmpTest{
-    protected static final String TAG = "RootPA-Test";
+    protected static final String TAG = "RootPA-T";
 
     protected final static int RETCODE_LENGTH=4;
     protected final static int SHA256_LENGTH=32;
@@ -213,7 +213,43 @@
         return cases;
     }
 
+    public static final List<CmpTest> generateErrorCases(){
+        ArrayList<CmpTest> cases=new ArrayList<CmpTest>();
+        cases.add(new CmpUnknown());
+        cases.add(new CmpTooLong());
+        cases.add(new CmpTooShort());
+        return cases;
+    }
 
+    public static final List<CmpTest> generateNoContainerCases(){
+        ArrayList<CmpTest> cases=new ArrayList<CmpTest>();
+
+        cases.add(new CmpBeginSpAuthentication());
+        cases.add(new CmpAuthenticate());
+        cases.add(new CmpTltContLockBySpNoContainer());
+        cases.add(new CmpAuthenticateTerminate());
+
+        return cases;
+    }
+
+    public static final List<CmpTest> generateNoStoreContainerCases(){
+        ArrayList<CmpTest> cases=new ArrayList<CmpTest>();
+        
+        cases.add(new CmpGenerateAuthTokenNoStore());       
+
+        return cases;
+    }
+
+    public static final List<CmpTest> generateResponseErrorCases(){
+        ArrayList<CmpTest> cases=new ArrayList<CmpTest>();
+
+        cases.add(new CmpGenerateAuthTokenResponseIdWrong());
+        cases.add(new CmpGenerateAuthTokenOffsetPlusLengthOut());
+        cases.add(new CmpGenerateAuthTokenOffsetOut());
+
+        return cases;
+    }
+    
     public CmpCommand createCommand(){
         return new CmpCommand(id_);    
     }    
@@ -258,7 +294,7 @@
             
         int returnCode=response.returnCode();
         if (returnCode!=0){
-            Log.e(TAG,"****NOTE: Return code from "+id_+" is different from 0: "+returnCode);
+            Log.e(TAG,"****NOTE: Return code from "+id_+" is different from 0: 0x"+ Integer.toHexString(returnCode));
             result_=false;
         }
 
diff --git a/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpTltContLockBySpNoContainer.java b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpTltContLockBySpNoContainer.java
new file mode 100755
index 0000000..f697c78
--- /dev/null
+++ b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpTltContLockBySpNoContainer.java
@@ -0,0 +1,86 @@
+/*
+Copyright  © Trustonic Limited 2013
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice, this 
+     list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright notice, 
+     this list of conditions and the following disclaimer in the documentation 
+     and/or other materials provided with the distribution.
+
+  3. Neither the name of the Trustonic Limited nor the names of its contributors 
+     may be used to endorse or promote products derived from this software 
+     without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
+OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+package com.gd.mobicore.pa.service.Test;
+
+import java.util.Arrays;
+import android.util.Log;
+import com.gd.mobicore.pa.ifc.CommandResult;
+import com.gd.mobicore.pa.ifc.CmpMsg;
+import com.gd.mobicore.pa.ifc.CmpCommand;
+import com.gd.mobicore.pa.ifc.CmpResponse;
+
+public class CmpTltContLockBySpNoContainer extends CmpTest{
+
+    protected final static byte[] TLTUUID_NO_CONTAINER={1,1,1,1,9,9,9,9,1,1,1,1,9,9,9,9};
+
+    protected final static int CMD_SPID_INDEX=CMD_HEADER_LENGTH;
+    protected final static int SPID_SIZE=4;
+    protected final static int CMD_TLTUUID_INDEX=CMD_SPID_INDEX + SPID_SIZE;
+    protected final static int CMD_MAC_INDEX=CMD_TLTUUID_INDEX + TLTUUID.length;
+
+    protected final static int RSP_TLTCONT_INDEX=RSP_HEADER_LENGTH+SIZEFIELD_LENGTH;
+    protected final static int RSP_MAC_INDEX=RSP_TLTCONT_INDEX + EXPECTED_TLT_CONT.length + HOW_MUCH_TLT_CONT_2_1_IS_BIGGER_THAN_OLD;
+
+    protected final static int MC_DRV_ERR_INVALID_DEVICE_FILE=0x00000010;
+    
+    public CmpTltContLockBySpNoContainer(){
+        super(CmpMsg.MC_CMP_CMD_TLT_CONT_LOCK_BY_SP);
+    }
+
+
+    public CmpCommand createCommand(){
+        CmpCommand command=new CmpCommand(id_);
+        command.setInt(CMD_SPID_INDEX, SPID);
+        command.setByteArray(CMD_TLTUUID_INDEX, TLTUUID_NO_CONTAINER);
+        command.setByteArray(CMD_MAC_INDEX, MAC);
+        return command;
+    }    
+    
+    public void checkResult(CmpResponse response){
+        result_=true;
+        
+        if(response==null){
+            Log.i(TAG,"response for "+id_+" is null");        
+            result_=false;
+            return;
+        }
+        
+        responseSize_=response.size();
+        Log.i(TAG,"size of "+id_+" response: "+responseSize_);
+
+        if (responseSize_!=0){ 
+            Log.e(TAG,"****NOTE: response size!=0");
+            result_=false;
+            return;
+        }
+        return;
+    }
+}
diff --git a/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpTooLong.java b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpTooLong.java
new file mode 100755
index 0000000..5c647eb
--- /dev/null
+++ b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpTooLong.java
@@ -0,0 +1,97 @@
+/*
+Copyright  © Trustonic Limited 2013
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice, this 
+     list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright notice, 
+     this list of conditions and the following disclaimer in the documentation 
+     and/or other materials provided with the distribution.
+
+  3. Neither the name of the Trustonic Limited nor the names of its contributors 
+     may be used to endorse or promote products derived from this software 
+     without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
+OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.gd.mobicore.pa.service.Test;
+
+import java.util.Arrays;
+import android.util.Log;
+import com.gd.mobicore.pa.ifc.CommandResult;
+import com.gd.mobicore.pa.ifc.CmpMsg;
+import com.gd.mobicore.pa.ifc.CmpCommand;
+import com.gd.mobicore.pa.ifc.CmpResponse;
+
+public class CmpTooLong extends CmpTest{
+    protected final static int CMD_TOO_LONG_TEST_IDX=400;
+    
+
+
+    protected final static byte[] EXPECTED_RND={3,3,3,3,3,3,3,3};
+    // using this instead of CmpTest.MAC, since the stub copies it from the container, it ensures the container is read
+    protected final static byte[] EXPECTED_MAC={9,9,9,9,9,9,9,9,0xA,0xA,0xA,0xA,0xA,0xA,0xA,0xA,0xA,0xA,0xA,0xA,0xA,0xA,0xA,0xA,0xA,0xA,0xA,0xA,0xB,0xB,0xB,0xB};
+    
+    public CmpTooLong(){
+        super(CmpMsg.MC_CMP_CMD_BEGIN_ROOT_AUTHENTICATION);
+        Log.i(TAG, "Creating too long authenticate message");        
+    }
+
+    protected final static int RSP_SUID_INDEX=RSP_HEADER_LENGTH;
+    protected final static int RSP_RND_INDEX=RSP_SUID_INDEX+EXPECTED_SUID.length;
+    protected final static int RSP_MAC_INDEX=RSP_RND_INDEX+EXPECTED_RND.length;
+
+    
+    public CmpCommand createCommand(){
+        CmpCommand command=new CmpCommand(id_);
+        command.setInt(CMD_TOO_LONG_TEST_IDX, 0xDEED);
+        return command;
+    }
+
+    // at this phase the command only contains the command id, RootPA adds the container to the command
+    // we can do that with base class method, no need to implement createCommand
+    
+    public void checkResult(CmpResponse response){
+        super.checkResult(response);
+        if(false==result_)return;
+
+    // these checks are here and pass just because mcStub is not too picky about the messages size
+    // for testing point of view it is important that RootPA does not crash and delivers the data as
+    // it receives it
+        
+        byte[] suid=response.getByteArray(RSP_SUID_INDEX, EXPECTED_SUID.length);
+        if(!Arrays.equals(suid, EXPECTED_SUID)){
+            Log.i(TAG, "CmpTooLong: wrong SUID:"+byteArrayToDisplayableString(suid));
+            result_=false;
+        }
+
+        byte[] rnd=response.getByteArray(RSP_RND_INDEX, EXPECTED_RND.length);
+        if(!Arrays.equals(rnd, EXPECTED_RND)){
+            Log.i(TAG, "CmpTooLong: wrong RND:"+byteArrayToDisplayableString(rnd));
+            result_=false;
+        }
+
+        byte[] mac=response.getByteArray(RSP_MAC_INDEX, EXPECTED_MAC.length);
+        if(!Arrays.equals(mac, EXPECTED_MAC)){
+            Log.i(TAG, "CmpTooLong: wrong MAC:"+byteArrayToDisplayableString(mac));
+            result_=false;
+        }
+
+        return;
+    }
+}
diff --git a/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpTooShort.java b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpTooShort.java
new file mode 100755
index 0000000..942071e
--- /dev/null
+++ b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpTooShort.java
@@ -0,0 +1,51 @@
+/*
+Copyright  © Trustonic Limited 2013
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice, this 
+     list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright notice, 
+     this list of conditions and the following disclaimer in the documentation 
+     and/or other materials provided with the distribution.
+
+  3. Neither the name of the Trustonic Limited nor the names of its contributors 
+     may be used to endorse or promote products derived from this software 
+     without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
+OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.gd.mobicore.pa.service.Test;
+
+import java.util.Arrays;
+import android.util.Log;
+import com.gd.mobicore.pa.ifc.CommandResult;
+import com.gd.mobicore.pa.ifc.CmpMsg;
+import com.gd.mobicore.pa.ifc.CmpCommand;
+import com.gd.mobicore.pa.ifc.CmpResponse;
+
+public class CmpTooShort extends CmpTest{
+    protected final static int CMD_MAC_IDX=CMD_HEADER_LENGTH+SIZEFIELD_LENGTH+80; 
+    protected final static int RSP_MAC_IDX=RSP_HEADER_LENGTH+SIZEFIELD_LENGTH+80;
+   
+    public CmpTooShort(){
+        super(CmpMsg.MC_CMP_CMD_AUTHENTICATE);
+        Log.i(TAG, "Creating too short authenticate message");
+    }
+
+    // using default commandCreator that only creates the header    
+}
diff --git a/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpUnknown.java b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpUnknown.java
new file mode 100755
index 0000000..42d93ab
--- /dev/null
+++ b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/CmpUnknown.java
@@ -0,0 +1,59 @@
+/*
+Copyright  © Trustonic Limited 2013
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice, this 
+     list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright notice, 
+     this list of conditions and the following disclaimer in the documentation 
+     and/or other materials provided with the distribution.
+
+  3. Neither the name of the Trustonic Limited nor the names of its contributors 
+     may be used to endorse or promote products derived from this software 
+     without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
+OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.gd.mobicore.pa.service.Test;
+
+import android.util.Log;
+import com.gd.mobicore.pa.ifc.CommandResult;
+import com.gd.mobicore.pa.ifc.CmpMsg;
+import com.gd.mobicore.pa.ifc.CmpResponse;
+
+public class CmpUnknown extends CmpTest{
+    private final static int MC_CMP_CMD_UNKNOWN_TEST=99;
+            
+    public CmpUnknown(){
+        super(MC_CMP_CMD_UNKNOWN_TEST);
+        Log.i(TAG, "Creating message with unknown command id");
+    }
+    
+   public void checkResult(CmpResponse response){
+        result_=true;       
+        responseSize_=response.size();
+        Log.i(TAG,"size of "+id_+" response: "+responseSize_);
+        if (responseSize_!=0){ 
+            Log.e(TAG,"****NOTE: response size=="+responseSize_+" expected 0");
+            result_=false;
+            return;
+        }
+        Log.i(TAG,"basic checks for "+id_+" done, returning "+result_);
+        return;
+    }    
+}
diff --git a/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/RootPAClient.java b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/RootPAClient.java
index f99f637..67964c7 100755
--- a/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/RootPAClient.java
+++ b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/RootPAClient.java
@@ -34,62 +34,38 @@
 import android.app.Activity;
 import android.os.Bundle;
 import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.BroadcastReceiver;
 import android.os.IBinder;
 import android.content.ServiceConnection;
 import android.content.ComponentName;
 import android.content.Context;
 import android.util.Log;
-import android.os.AsyncTask;
+
 
 // import android.os.RemoteException;
 
 import java.util.List;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.lang.Integer;
-import java.util.UUID;
-       
+     
 import com.gd.mobicore.pa.ifc.RootPAProvisioningIntents;
-import com.gd.mobicore.pa.ifc.RootPAServiceIfc;
-import com.gd.mobicore.pa.ifc.RootPADeveloperIfc;
-import com.gd.mobicore.pa.ifc.RootPAOemIfc;
-import com.gd.mobicore.pa.ifc.CmpMsg;
-import com.gd.mobicore.pa.ifc.CmpCommand;
-import com.gd.mobicore.pa.ifc.CmpResponse;
-import com.gd.mobicore.pa.ifc.CommandResult;
-import com.gd.mobicore.pa.ifc.BooleanResult;
-import com.gd.mobicore.pa.ifc.SPID;
-import com.gd.mobicore.pa.ifc.Version;
-import com.gd.mobicore.pa.ifc.SUID;
-import com.gd.mobicore.pa.ifc.SPContainerStructure;
-import com.gd.mobicore.pa.ifc.SPContainerStateParcel;
-import com.gd.mobicore.pa.ifc.SPContainerState;
-import com.gd.mobicore.pa.ifc.TrustletContainer;
-import com.gd.mobicore.pa.ifc.TrustletContainerState;
 
 public class RootPAClient extends Activity {
 
-    RootPAServiceIfc provisioningServiceIfc_=null; 
-    boolean provisioningServiceIsBound;
-
-    RootPADeveloperIfc developerServiceIfc_=null;
-    boolean developerServiceIsBound;    
-
-    RootPAOemIfc oemServiceIfc_=null;
-    boolean oemServiceIsBound;    
+    boolean provisioningServiceIsBound_;
+    boolean developerServiceIsBound_;    
+    boolean oemServiceIsBound_;
 
     List<String> stringList_=new ArrayList<String>();
     boolean allTestsPassed_ = true;
     
     private static final String TESTTAG = "RootPA-Test";
-    private static final String TAG = "RootPA-J";
+    private static final String TAG = "RootPA-T";
 
     private int callCounter_=0;
-    private void printFinalResults()
+    void printFinalResults()
     {
-        if(++callCounter_==3){ // number of services
+        Log.i(TAG,"printFinalResults "+callCounter_);        
+        if(--callCounter_==0){ // number of services
 
             Log.i(TESTTAG,"==========================================================================");            
             Log.i(TESTTAG,"================= Execution of tests "+(allTestsPassed_?"PASSED":"FAILED"));
@@ -105,73 +81,106 @@
             }        
         }
     }
-        
-    private ServiceConnection developerServiceConnection = new ServiceConnection(){
+
+    private TestDeveloperService testDeveloperService_=null;
+    private ServiceConnection developerServiceConnection_ = new ServiceConnection(){
         public void onServiceDisconnected(ComponentName className){
-            developerServiceIfc_=null;
+            testDeveloperService_.disconnect();
         }
         public void onServiceConnected(ComponentName className, IBinder service){
-            new TestDeveloperService().execute(service);
+            testDeveloperService_=new TestDeveloperService(RootPAClient.this);
+            testDeveloperService_.execute(service);
         }
     };
 
-   
-    private ServiceConnection oemServiceConnection = new ServiceConnection(){
+    private TestOemService testOemService_=null;   
+    private ServiceConnection oemServiceConnection_ = new ServiceConnection(){
         public void onServiceDisconnected(ComponentName className){
-            oemServiceIfc_=null; 
+            testOemService_.disconnect();
         }
         public void onServiceConnected(ComponentName className, IBinder service){
-            new TestOemService().execute(service);
+            testOemService_=new TestOemService(RootPAClient.this);
+            testOemService_.execute(service);
         }
     };
 
-
-    private ServiceConnection provisioningServiceConnection = new ServiceConnection(){
+    private TestProvisioningService testProvisioningService_=null;   
+    private ServiceConnection provisioningServiceConnection_ = new ServiceConnection(){
         public void onServiceDisconnected(ComponentName className){
-            provisioningServiceIfc_=null; 
+            testProvisioningService_.disconnect();
         }
 
         public void onServiceConnected(ComponentName className, IBinder service){
-            new TestProvisioningService().execute(service);
+            testProvisioningService_=new TestProvisioningService(RootPAClient.this);
+            testProvisioningService_.execute(service);
         }
-    };
-
+    }; 
+    
     void doBindService(){       
         
-        byte[] address="http://10.0.2.2:80/".getBytes(); // using local apache2 server
-        Intent psintent=new Intent("com.gd.mobicore.pa.service.PROVISIONING_SERVICE");
-        psintent.putExtra("SE", address);
-        bindService(psintent, provisioningServiceConnection, Context.BIND_AUTO_CREATE);
-        provisioningServiceIsBound=true;
         
-        Intent dsintent=new Intent("com.gd.mobicore.pa.service.DEVELOPER_SERVICE");
-        dsintent.putExtra("SE", address);
-        bindService(dsintent, developerServiceConnection, Context.BIND_AUTO_CREATE);       
-        developerServiceIsBound=true;
+        byte[] address="https://195.81.216.155:44378/service-enabler/enrollment/".getBytes(); // using local apache2 server
+//        byte[] address="https://10.0.2.2:443/".getBytes(); // using local apache2 server
+        int loggingLevel=android.util.Log.DEBUG;
+        try{
+            Intent psintent=new Intent(RootPAProvisioningIntents.PROVISIONING_SERVICE);
+            psintent.putExtra("SE", address);
+            psintent.putExtra("LOG", loggingLevel);        
+            bindService(psintent, provisioningServiceConnection_, Context.BIND_AUTO_CREATE);
+            provisioningServiceIsBound_=true;
+            callCounter_++;
+        
+            Intent dsintent=new Intent(RootPAProvisioningIntents.DEVELOPER_SERVICE);
+            dsintent.putExtra("SE", address);
+            dsintent.putExtra("LOG", loggingLevel);
+            bindService(dsintent, developerServiceConnection_, Context.BIND_AUTO_CREATE);       
+            developerServiceIsBound_=true;
+            callCounter_++;            
 
-        Intent osintent=new Intent("com.gd.mobicore.pa.service.OEM_SERVICE");
-        osintent.putExtra("SE", address);
-        bindService(osintent, oemServiceConnection, Context.BIND_AUTO_CREATE);       
-        oemServiceIsBound=true;
+            Intent osintent=new Intent(RootPAProvisioningIntents.OEM_SERVICE);
+            osintent.putExtra("SE", address);
+            osintent.putExtra("LOG", loggingLevel);        
+            bindService(osintent, oemServiceConnection_, Context.BIND_AUTO_CREATE);       
+            oemServiceIsBound_=true;
+            callCounter_++;
+            
+        }catch(Exception e){
+            Log.e(TAG,"an exception received in bingind "+e);
+        }
 
         Log.d(TAG,"===Binding done");
     }
 
+    
+    void bindServiceWrongIp(ServiceConnection oemServiceWrongIpConnection){
+        byte[] address="http://10.255.255.8:9/".getBytes(); // this is supposed to be nonexistent address,
+        int loggingLevel=android.util.Log.DEBUG;
+
+        Intent osintent=new Intent(RootPAProvisioningIntents.OEM_SERVICE);
+        osintent.putExtra("SE", address);
+        osintent.putExtra("LOG", loggingLevel);        
+        bindService(osintent, oemServiceWrongIpConnection, Context.BIND_AUTO_CREATE);       
+    }
+
+    void unbindServiceWrongIp(ServiceConnection oemServiceWrongIpConnection){
+        unbindService(oemServiceWrongIpConnection);
+    }
+    
     void doUnbindService(){
         Log.d(TAG,"===Unbinding");
-        if(provisioningServiceIsBound){
-            unbindService(provisioningServiceConnection);
-            provisioningServiceIsBound=false;
+        if(provisioningServiceIsBound_){
+            unbindService(provisioningServiceConnection_);
+            provisioningServiceIsBound_=false;
         }
 
-        if(developerServiceIsBound){
-            unbindService(developerServiceConnection);
-            developerServiceIsBound=false;
+        if(developerServiceIsBound_){
+            unbindService(developerServiceConnection_);
+            developerServiceIsBound_=false;
         }
 
-        if(oemServiceIsBound){
-            unbindService(oemServiceConnection);
-            oemServiceIsBound=false;
+        if(oemServiceIsBound_){
+            unbindService(oemServiceConnection_);
+            oemServiceIsBound_=false;
         }
     }
    
@@ -188,1065 +197,4 @@
         doUnbindService();
         System.exit(0);    
     }
-    
-    private class TestDeveloperService extends AsyncTask<IBinder, Void, Void> {
-        protected Void doInBackground(IBinder... s) {
-            IBinder service=s[0];
-            boolean res=true;
-            developerServiceIfc_= RootPADeveloperIfc.Stub.asInterface(service);
-            if(developerServiceIfc_ == null){
-                Log.e(TAG,"FAILURE: no developerServiceIfc_, why?");
-            }
-
-            try{
-                Log.d(TAG, "testInstallTrustlet");
-                res=testInstallTrustlet(stringList_);
-            }catch(Throwable e){
-                Log.e(TAG, "Executing testInstallTrustlet failed due to exception "+e);
-                res=false;
-            }
-            allTestsPassed_=(allTestsPassed_==false)?allTestsPassed_:res;
-            Log.i(TESTTAG,((res==true)?"SUCCESS":"FAILURE")+": Test installTrustlet");
-            
-            printFinalResults();
-            return null;
-        }
-
-        private final byte[] TEST_TRUSTLET={
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  // 200
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  // 400
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  // 600
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  // 800
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  // 1000
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  // 1200
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  // 1400
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  // 1600
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  // 1800
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  // 2000
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1  // 2200
-            };
-            
-        private final byte[] TEST_KEY={
-            1,1,1,1,1,1,1,1,1,1,            
-            2,2,2,2,2,2,2,2,2,2,
-            3,3,3,3,3,3,3,3,3,3,
-            4,4
-            };
-
-        byte[] trustlet_;
-        boolean done_=false;
-            
-        boolean testInstallTrustlet(List<String> stringList){
-            String logi=new String();            
-            boolean overallsuccess=true;
-            CommandResult tret=new CommandResult(0xFFFF0000);
-            CommandResult kret=new CommandResult(0xFFFF0000);
-            
-        // set receiver for intents
-        
-            android.os.HandlerThread handlerThread = new android.os.HandlerThread("tltIntentReceiverThread");
-
-            handlerThread.start();
-            android.os.Looper looper = handlerThread.getLooper();
-            android.os.Handler handler= new android.os.Handler(looper);
-            BroadcastReceiver receiver=new BroadcastReceiver(){
-                public void onReceive(Context ctx, Intent intent){
-                    trustlet_ = intent.getByteArrayExtra(RootPAProvisioningIntents.TRUSTLET);
-                    Log.d(TAG, "Received install tlt intent");
-
-                }
-            };
-            IntentFilter filter=new IntentFilter(RootPAProvisioningIntents.INSTALL_TRUSTLET);
-            registerReceiver(receiver, filter, null, handler);
-          
-            BroadcastReceiver statusreceiver=new BroadcastReceiver(){
-                public void onReceive(Context ctx, Intent intent){
-                    int status = intent.getIntExtra(RootPAProvisioningIntents.STATE, 0);
-                    Log.d(TAG, "Received status intent for install trustlet: "+status);
-                    if(status==RootPAProvisioningIntents.FINISHED_PROVISIONING){
-                        done_=true;
-                    }                        
-                }
-            };
-            IntentFilter statusfilter=new IntentFilter(RootPAProvisioningIntents.PROVISIONING_PROGRESS_UPDATE);
-            registerReceiver(statusreceiver, statusfilter, null, handler);
-
-            
-            try{
-                tret=developerServiceIfc_.installTrustlet(TEST_TRUSTLET, null);
-            }catch(Throwable e){
-                logi = logi.concat("FAILURE: call to installTrustlet with trustlet failed: " + e + "\n");
-                overallsuccess=false;
-            }            
-
-            if(tret.isOk()){
-                try {
-                    int totalTime=0;
-                    while(done_==false){
-                        Thread.sleep(500);
-                        totalTime+=500;
-                        if(totalTime>3000){
-                            break;
-                        }
-                    }
-                    Log.d(TAG, "totalTime: "+totalTime);
-                    Thread.sleep(1000); // waiting for one more second to ensure the locks are opened for the following tests    
-                } catch (Exception e) {
-                    Log.d(TAG, "sleep failed "+e);
-                }
-            }
-            else
-            {
-                Log.d(TAG, "error when calling installTrustlet for tlt"+tret);                
-            }
-
-            done_=false; // another call
-            try{
-                kret=developerServiceIfc_.installTrustlet(null, TEST_KEY);
-            }catch(Throwable e){
-                logi = logi.concat("FAILURE: call to installTrustlet with key failed: " + e + "\n");
-                overallsuccess=false;
-            }
-
-            if(kret.isOk()){
-                try {
-                    int totalTime=0;
-                    while(done_==false){
-                        Thread.sleep(500);
-                        totalTime+=500;
-                        if(totalTime>3000){
-                            break;
-                        }
-                    }
-                    Log.d(TAG, "totalTime: "+totalTime);
-                    Thread.sleep(1000); // waiting for one more second to ensure the locks are opened for the following tests    
-                } catch (Exception e) {
-                    Log.d(TAG, "sleep failed "+e);
-                }
-            }
-            else
-            {
-                Log.d(TAG, "error when calling installTrustlet for key "+kret);                
-            }            
-            
-            unregisterReceiver(receiver);
-            unregisterReceiver(statusreceiver);
-            handlerThread.quit();            
-            
-            if(trustlet_!=null){
-                boolean trustletStatus=Arrays.equals(trustlet_,TEST_TRUSTLET);
-                Log.d(TAG,"trustletStatus "+trustletStatus+" "+trustlet_.length+" "+TEST_TRUSTLET.length);
-                overallsuccess=!overallsuccess?overallsuccess:trustletStatus;
-            }else{
-                overallsuccess=false;
-            }
-            overallsuccess=!overallsuccess?overallsuccess:(tret.isOk());
-            overallsuccess=!overallsuccess?overallsuccess:(kret.isOk());
-
-            logi = logi.concat("================= Results of testing installTrustlet: ").concat(((overallsuccess==true)?"SUCCESS":"FAILURE")+"\n");            
-            logi = logi.concat(((tret.isOk())?"SUCCESS":"FAILURE")+": Testing installTrustlet, tlt "+((tret.isOk())?"\n":("returned: " +tret+" \n")));
-            logi = logi.concat(((trustlet_!=null && Arrays.equals(trustlet_,TEST_TRUSTLET))?"SUCCESS":"FAILURE")+": Testing installTrustlet, tlt content in the intent\n");
-            logi = logi.concat(((kret.isOk())?"SUCCESS":"FAILURE")+": Testing installTrustlet, key "+((kret.isOk())?"\n":("returned: " +kret+" \n")));
-            logi = logi.concat("==========================================================================\n");
-
-            stringList.add(logi);
-            return overallsuccess;            
-        }
-    }
-
-    private class TestProvisioningService extends AsyncTask<IBinder, Void, Void> {
-        protected Void doInBackground(IBinder... service) {
-            provisioningServiceIfc_= RootPAServiceIfc.Stub.asInterface(service[0]);
-            if(provisioningServiceIfc_ == null){
-                Log.e(TAG,"FAILURE: no provisioningServiceIfc_, why?");            
-            }
-
-            String s=null;
-            boolean res=true;
-        
-            try{
-                Log.d(TAG, "testCmpCommands");
-                res=testCmpCommands(stringList_);
-            }catch(Throwable e){
-                Log.e(TAG, "Executing testCmpCommands failed due to exception "+e);
-                res=false;
-            }
-
-            allTestsPassed_=(allTestsPassed_==false)?allTestsPassed_:res;
-            Log.i(TESTTAG,"=========================================================================="); 
-            Log.i(TESTTAG,((res==true)?"SUCCESS":"FAILURE")+": Test executeCmpCommands");
-
-            try{
-                Log.d(TAG, "testRegistrationStatus");
-                res=testRegistrationStatus(stringList_);
-            }catch(Throwable e){
-                Log.e(TAG, "Executing testRegistrationStatus failed due to exception "+e);
-                res=false;
-            }
-            allTestsPassed_=(allTestsPassed_==false)?allTestsPassed_:res;
-            Log.i(TESTTAG,((res==true)?"SUCCESS":"FAILURE")+": Test isRootContainerRegistered and isSPContainerRegistered");
-
-            try{
-                Log.d(TAG, "testGetters");
-                res=testGetters(stringList_);
-            }catch(Throwable e){
-                Log.e(TAG, "Executing testGetters failed due to exception "+e);
-                res=false;
-            }
-            allTestsPassed_=(allTestsPassed_==false)?allTestsPassed_:res;
-            Log.i(TESTTAG,((res==true)?"SUCCESS":"FAILURE")+": Test getVersion and getDeviceId");
-
-            try{
-                Log.d(TAG, "testLock");
-                res=testLock(stringList_);
-            }catch(Throwable e){
-                Log.e(TAG, "Executing testLock failed due to exception "+e);
-                res=false;
-            }
-            allTestsPassed_=(allTestsPassed_==false)?allTestsPassed_:res;
-            Log.i(TESTTAG,((res==true)?"SUCCESS":"FAILURE")+": Test acquireLock and releaseLock");
-
-            try{
-                Log.d(TAG, "testDoProvisioning");
-                res=testDoProvisioning(stringList_);
-            }catch(Throwable e){
-                Log.e(TAG, "Executing testDoProvisioning failed due to exception "+e);
-                res=false;
-            }
-            allTestsPassed_=(allTestsPassed_==false)?allTestsPassed_:res;
-            Log.i(TESTTAG,((res==true)?"SUCCESS":"FAILURE")+": Test doProvisioning");
-
-            try{
-                Log.d(TAG, "testContainerStructureAndState");
-                res=testContainerStructureAndState(stringList_);
-            }catch(Throwable e){
-                Log.e(TAG, "Executing testContainerStructureAndState failed due to exception "+e);
-                res=false;
-            }
-            allTestsPassed_=(allTestsPassed_==false)?allTestsPassed_:res;
-            Log.i(TESTTAG,((res==true)?"SUCCESS":"FAILURE")+": Test getSPContainerStructure and getSPContainerState");
-
-            try{
-                Log.d(TAG, "testSessionHandling");
-                res=testSessionHandling(stringList_);
-            }catch(Throwable e){
-                Log.e(TAG, "Executing testSessionHandling failed due to exception "+e);
-                res=false;
-            }
-            allTestsPassed_=(allTestsPassed_==false)?allTestsPassed_:res;
-            Log.i(TESTTAG,((res==true)?"SUCCESS":"FAILURE")+": Test session handling");
-            
-            printFinalResults();
-            return null;
-        }
-
-        public void onServiceDisconnected(ComponentName className){
-            provisioningServiceIfc_=null; 
-        }
-
-        /**
-        Test content management protocol commands
-        */
-        private boolean testCmpCommands(List<String> stringList){
-            String logi=new String();
-            CommandResult  res=new CommandResult(0xFFFF0000);
-            int uid=129;
-            List<CmpCommand> commands=null;
-            List<CmpResponse> responses=null;
-            
-            List<CmpTest> cmpTestCases = CmpTest.generateAll();
-            try{
-                commands=new ArrayList<CmpCommand>();
-                responses=new ArrayList<CmpResponse>();
-                for(int i=0; i<cmpTestCases.size(); i++){
-                    commands.add(cmpTestCases.get(i).createCommand());
-                    commands.get(i).setIgnoreError(true);
-                }
-            }catch(java.lang.Exception e){
-                Log.e(TAG,"FAILURE: broken test case, initializing data failed: ",e);
-            }           
-
-            try{
-                provisioningServiceIfc_.acquireLock(uid); // no checking of return value since we do not test lock here (might help in debugging though)
-                res=provisioningServiceIfc_.executeCmpCommands(uid, commands, responses);
-                provisioningServiceIfc_.releaseLock(uid); // no checking of return value since we do not test lock here (might help in debugging though)
-            }catch(Throwable e){
-                res = new CommandResult(0xFFFFFFFF);
-                logi = logi.concat("FAILURE: call to executeCmpCommands failed: " + e + "\n");
-            }           
-            boolean success=true;
-            boolean overallsuccess=success;
-            
-
-            for(int i=0; i<cmpTestCases.size(); i++){
-                try{
-                    cmpTestCases.get(i).checkResult(responses.get(i));
-                } catch(java.lang.Exception e){
-                    Log.e(TAG,"FAILURE: checking results from test "+ cmpTestCases.get(i).id() +" failed: ",e);
-                }                   
-            }
-
-            overallsuccess=res.isOk();
-            logi = logi.concat("================= Results of testing executeCmpCommands\n");
-            logi = logi.concat(((overallsuccess==true)?"SUCCESS":"FAILURE")+": executeCmpCommands returned: "+res+"\n");
-            for(int i=0; i<cmpTestCases.size(); i++){
-                logi = logi.concat(((cmpTestCases.get(i).result_==true)?"SUCCESS":"FAILURE")+": Testing "+cmpTestCases.get(i).id()+"\n");
-                overallsuccess=(overallsuccess==true)?cmpTestCases.get(i).result_:overallsuccess;
-            }
-            logi = logi.concat("==========================================================================\n");
-            stringList.add(logi);
-            return overallsuccess;
-        }
-
-        private SPID TEST_SPID;
-        private static final int TEST_UID=0xFFFF0000;
-        private static final int TEST_UID_LOCKED=4321;
-        
-        private boolean testRegistrationStatus(List<String> stringList){
-
-            TEST_SPID = new SPID(8);
-            String logi=new String();
-            boolean overallsuccess=true;
-
-            BooleanResult rcResult=new BooleanResult(false);
-            BooleanResult scResult=new BooleanResult(false);
-
-            CommandResult rcRet = new CommandResult(0xFFFF0000);
-            CommandResult scRet = new CommandResult(0xFFFF0000);
-
-            try{
-                rcRet = provisioningServiceIfc_.isRootContainerRegistered(rcResult);
-            }catch(Throwable e){
-                logi = logi.concat("FAILURE: call to isRootContainerRegistered failed: " + e + "\n");
-                rcRet = new CommandResult(0xFFFFFFFF);
-                overallsuccess=false;
-            }
-
-            try{
-                scRet = provisioningServiceIfc_.isSPContainerRegistered(TEST_SPID, scResult);
-            }catch(Throwable e){
-                logi = logi.concat("FAILURE: call to isSPContainerRegistered failed: " + e + "\n");
-                scRet = new CommandResult(0xFFFFFFFF);
-                overallsuccess=false;
-            }
-
-            overallsuccess=!overallsuccess?overallsuccess:(rcRet.isOk());
-            overallsuccess=!overallsuccess?overallsuccess:(rcResult.result()==true);
-            overallsuccess=!overallsuccess?overallsuccess:(scRet.isOk());
-            overallsuccess=!overallsuccess?overallsuccess:(scResult.result()==true);            
-
-            logi = logi.concat("================= Results of testing registration status: ").concat(((overallsuccess==true)?"SUCCESS":"FAILURE")+"\n");
-            logi = logi.concat(((rcRet.isOk())?"SUCCESS":"FAILURE")+": Testing isRootContainerRegistered "+((rcRet.isOk())?"\n":("returned: " +rcRet+" \n")));
-            logi = logi.concat(((rcResult.result()==true)?"SUCCESS":"FAILURE")+": Testing isRootContainerRegistered boolean result "+((rcResult.result()==true)?"\n":("is not registered even though expected\n")));
-
-            logi = logi.concat(((scRet.isOk())?"SUCCESS":"FAILURE")+": Testing isSPContainerRegistered "+((scRet.isOk())?"\n":("returned: " +scRet+" \n")));
-            logi = logi.concat(((scResult.result()==true)?"SUCCESS":"FAILURE")+": Testing isSPContainerRegistered boolean result "+((scResult.result()==true)?"\n":("is not registered even though expected\n"))); 
-            logi = logi.concat("==========================================================================\n");
-
-            stringList.add(logi);            
-            return overallsuccess;
-        }
-        
-        private boolean testGetters(List<String> stringList){
-
-            String logi=new String();
-            boolean overallsuccess=true;
-            CommandResult gvRet=new CommandResult(0xFFFF0000);
-            CommandResult gdiRet=new CommandResult(0xFFFF0000);
-            SUID test_suid = new SUID();
-            Version test_version = new Version();
-            final String EXPECTED_PRODUCT_ID="xxxxx";
-            final int EXPECTED_TAG=2;
-            final int EXPECTED_MCI=1;
-            final int EXPECTED_SO=2;
-            final int EXPECTED_MCLF=3;
-            final int EXPECTED_CONT=4;            
-            final int EXPECTED_MCCONF=5;
-            final int EXPECTED_TLAPI=6;
-            final int EXPECTED_DRAPI=7;
-            final int EXPECTED_CMP=8;
-
-            try{
-                gvRet=provisioningServiceIfc_.getVersion(test_version);
-            }catch(Throwable e){
-                logi = logi.concat("FAILURE: call to getVersion failed: " + e + "\n");
-                gvRet = new CommandResult(0xFFFFFFFF);
-                overallsuccess=false;
-            }
-
-            try{
-                gdiRet=provisioningServiceIfc_.getDeviceId(test_suid);        
-            }catch(Throwable e){
-                logi = logi.concat("FAILURE: call to getDeviceId failed: " + e + "\n");
-                gdiRet = new CommandResult(0xFFFFFFFF);
-                overallsuccess=false;
-            }
-
-
-            int tag=test_version.version().getInt("TAG");
-            int mci=test_version.version().getInt("MCI");
-            int so=test_version.version().getInt("SO");
-            int mclf=test_version.version().getInt("MCLF");
-            int cont=test_version.version().getInt("CONT");
-            int mcconf=test_version.version().getInt("MCCONF");
-            int tlapi=test_version.version().getInt("TLAPI");
-            int drapi=test_version.version().getInt("DRAPI");
-            int cmp=test_version.version().getInt("CMP");
-
-
-            overallsuccess=!overallsuccess?overallsuccess:(gvRet.isOk());
-            overallsuccess=!overallsuccess?overallsuccess:(test_version.productId().compareTo(EXPECTED_PRODUCT_ID)==0);
-            overallsuccess=!overallsuccess?overallsuccess:(tag==EXPECTED_TAG);
-            overallsuccess=!overallsuccess?overallsuccess:(mci==EXPECTED_MCI);
-            overallsuccess=!overallsuccess?overallsuccess:(so==EXPECTED_SO);
-            overallsuccess=!overallsuccess?overallsuccess:(mclf==EXPECTED_MCLF);
-            overallsuccess=!overallsuccess?overallsuccess:(cont==EXPECTED_CONT);            
-            overallsuccess=!overallsuccess?overallsuccess:(mcconf==EXPECTED_MCCONF);
-            overallsuccess=!overallsuccess?overallsuccess:(tlapi==EXPECTED_TLAPI);
-            overallsuccess=!overallsuccess?overallsuccess:(drapi==EXPECTED_DRAPI);                        
-            overallsuccess=!overallsuccess?overallsuccess:(cmp==EXPECTED_CMP);
-
-            overallsuccess=!overallsuccess?overallsuccess:(gdiRet.isOk());
-            overallsuccess=!overallsuccess?overallsuccess:(Arrays.equals(test_suid.suid(),CmpTest.EXPECTED_SUID));
-
-            logi = logi.concat("================= Results of testing getters: ").concat(((overallsuccess==true)?"SUCCESS":"FAILURE")+"\n");          
-            logi = logi.concat(((gvRet.isOk())?"SUCCESS":"FAILURE")+": Testing getVersion "+((gvRet.isOk())?" \n":("returned: " +gvRet+" \n")));
-            logi = logi.concat(((test_version.productId().compareTo(EXPECTED_PRODUCT_ID)==0)?"SUCCESS":"FAILURE")+": Testing getVersion, productId "+((
-                    test_version.productId().compareTo(EXPECTED_PRODUCT_ID)==0)?" \n":("productId: " +test_version.productId()+" \n")));
-            logi = logi.concat(((tag==EXPECTED_TAG)?"SUCCESS":"FAILURE")+": Testing getVersion, tag"+((tag==EXPECTED_TAG)?" \n":(": " +tag+" \n")));
-            logi = logi.concat(((mci==EXPECTED_MCI)?"SUCCESS":"FAILURE")+": Testing getVersion, mci"+((mci==EXPECTED_MCI)?" \n":(": " +mci+" \n")));
-            logi = logi.concat(((so==EXPECTED_SO)?"SUCCESS":"FAILURE")+": Testing getVersion, so"+((so==EXPECTED_SO)?" \n":(": " +so+" \n")));
-            logi = logi.concat(((mclf==EXPECTED_MCLF)?"SUCCESS":"FAILURE")+": Testing getVersion, mclf"+((mclf==EXPECTED_MCLF)?" \n":(": " +mclf+" \n")));
-            logi = logi.concat(((cont==EXPECTED_CONT)?"SUCCESS":"FAILURE")+": Testing getVersion, cont"+((cont==EXPECTED_CONT)?" \n":(": " +cont+" \n")));
-            logi = logi.concat(((mcconf==EXPECTED_MCCONF)?"SUCCESS":"FAILURE")+": Testing getVersion, mcconf"+((mcconf==EXPECTED_MCCONF)?" \n":(": " +mcconf+" \n")));
-            logi = logi.concat(((tlapi==EXPECTED_TLAPI)?"SUCCESS":"FAILURE")+": Testing getVersion, tlapi"+((tlapi==EXPECTED_TLAPI)?" \n":(": " +tlapi+" \n")));
-            logi = logi.concat(((drapi==EXPECTED_DRAPI)?"SUCCESS":"FAILURE")+": Testing getVersion, drapi"+((drapi==EXPECTED_DRAPI)?" \n":(": " +drapi+" \n")));
-            logi = logi.concat(((cmp==EXPECTED_CMP)?"SUCCESS":"FAILURE")+": Testing getVersion, cmp"+((cmp==EXPECTED_CMP)?" \n":(": " +cmp+" \n")));
-
-
-            logi = logi.concat(((gdiRet.isOk())?"SUCCESS":"FAILURE")+": Testing getDeviceId "+((gdiRet.isOk())?" \n":("returned: " +gdiRet+" \n")));
-            logi = logi.concat(((Arrays.equals(test_suid.suid(),CmpTest.EXPECTED_SUID))?"SUCCESS":"FAILURE")+": Testing getDeviceId, suid "+((Arrays.equals(test_suid.suid(),CmpTest.EXPECTED_SUID))?" \n":("returned: " +CmpTest.byteArrayToDisplayable(test_suid.suid())+" \n")));
-            logi = logi.concat("==========================================================================\n");
-
-            stringList.add(logi);
-            return overallsuccess;
-        }
-
-        private boolean testLock(List<String> stringList){
-
-            String logi=new String();
-            boolean overallsuccess=true;
-            CommandResult alRet=new CommandResult(0xFFFF0000);
-            CommandResult alLockedRet=new CommandResult(0xFFFF0000);
-            CommandResult rlLockedRet=new CommandResult(0xFFFF0000);
-            CommandResult rlRet=new CommandResult(0xFFFF0000);
-            CommandResult rlOpenRet=new CommandResult(0xFFFF0000);
-
-        // first test locking when the lock is open            
-            try{
-                alRet=provisioningServiceIfc_.acquireLock(TEST_UID);
-            }catch(Throwable e){
-                logi = logi.concat("FAILURE: call to acquireLock failed: " + e + "\n");
-                alRet = new CommandResult(0xFFFFFFFF);
-                overallsuccess=false;
-            }
-
-        // then test locking when the lock is aquired 
-            try{
-                alLockedRet=provisioningServiceIfc_.acquireLock(TEST_UID_LOCKED);
-            }catch(Throwable e){
-                logi = logi.concat("FAILURE: call to acquireLock failed: " + e + "\n");
-                alLockedRet = new CommandResult(0xFFFFFFFF);
-                overallsuccess=false;
-            }
-        
-        // then test opening the lock with wrong UID when the lock is aquired 
-            try{
-                rlLockedRet=provisioningServiceIfc_.releaseLock(TEST_UID_LOCKED);        
-            }catch(Throwable e){
-                logi = logi.concat("FAILURE: call to releaseLock failed: " + e + "\n");
-                rlLockedRet = new CommandResult(0xFFFFFFFF);
-                overallsuccess=false;
-            }
-
-        // then test opening the lock when the lock is aquired 
-            try{
-                rlRet=provisioningServiceIfc_.releaseLock(TEST_UID);        
-            }catch(Throwable e){
-                logi = logi.concat("FAILURE: call to releaseLock failed: " + e + "\n");
-                rlRet = new CommandResult(0xFFFFFFFF);
-                overallsuccess=false;
-            }
-
-        // then test opening the lock when already open
-            try{
-                rlOpenRet=provisioningServiceIfc_.releaseLock(TEST_UID);        
-            }catch(Throwable e){
-                logi = logi.concat("FAILURE: call to releaseLock failed: " + e + "\n");
-                rlOpenRet = new CommandResult(0xFFFFFFFF);
-                overallsuccess=false;
-            }
-
-            overallsuccess=!overallsuccess?overallsuccess:(alRet.isOk());
-            overallsuccess=!overallsuccess?overallsuccess:(alLockedRet.result()==CommandResult.ROOTPA_ERROR_LOCK);
-            overallsuccess=!overallsuccess?overallsuccess:(rlLockedRet.result()==CommandResult.ROOTPA_ERROR_LOCK);
-            overallsuccess=!overallsuccess?overallsuccess:(rlRet.isOk());
-            overallsuccess=!overallsuccess?overallsuccess:(rlOpenRet.isOk());
-
-            logi = logi.concat("================= Results of testing lock: ").concat(((overallsuccess==true)?"SUCCESS":"FAILURE")+"\n");
-            logi = logi.concat(((alRet.isOk())?"SUCCESS":"FAILURE")+": Testing acquireLock "+((alRet.isOk())?" \n":("returned: " +alRet+" \n")));
-            logi = logi.concat(((alLockedRet.result()==CommandResult.ROOTPA_ERROR_LOCK)?"SUCCESS":"FAILURE")+": Testing acquireLock locked"+
-                   ((alLockedRet.result()==CommandResult.ROOTPA_ERROR_LOCK)?" \n":("returned: " +alLockedRet+" \n")));
-
-            logi = logi.concat(((rlLockedRet.result()==CommandResult.ROOTPA_ERROR_LOCK)?"SUCCESS":"FAILURE")+": Testing releaseLock locked with different uid "+
-                   ((rlLockedRet.result()==CommandResult.ROOTPA_ERROR_LOCK)?" \n":("returned: " +rlLockedRet+" \n")));
-
-            logi = logi.concat(((rlRet.isOk())?"SUCCESS":"FAILURE")+": Testing releaseLock "+((rlRet.isOk())?" \n":("returned: " +rlRet+" \n")));            
-            logi = logi.concat(((rlOpenRet.isOk())?"SUCCESS":"FAILURE")+": Testing releaseLock already open "+((rlOpenRet.isOk())?" \n":("returned: " +rlOpenRet+" \n")));            
-            logi = logi.concat("==========================================================================\n");
-
-            
-
-            
-            stringList.add(logi);
-            return overallsuccess;
-        }
-
-        final boolean[] intentsReceived_=new boolean[7]; // 7 == number of intents to be received
-        
-        private synchronized boolean allIntentsReceived(){
-            return (intentsReceived_[0] && intentsReceived_[1] && intentsReceived_[2] && intentsReceived_[3] && intentsReceived_[4] && intentsReceived_[5] && intentsReceived_[6]);
-        }
-
-        private boolean someIntentsReceived(){
-            return (intentsReceived_[0] ^ intentsReceived_[1] ^ intentsReceived_[2] ^ intentsReceived_[3] ^ intentsReceived_[4] ^ intentsReceived_[5] ^ intentsReceived_[6]);
-        }
-        
-        private synchronized void markIntentReceived(int i){
-            intentsReceived_[i]=true;
-        }
-
-        private int statusToIndex(int status){
-            switch (status){
-                case RootPAProvisioningIntents.CONNECTING_SERVICE_ENABLER:
-                    return 1; //C_CONNECTING_SERVICE_ENABLER;
-                case RootPAProvisioningIntents.AUTHENTICATING_SOC:
-                    return 2; //C_AUTHENTICATING_SOC;
-                case RootPAProvisioningIntents.AUTHENTICATING_ROOT:
-                    return 3; //C_AUTHENTICATING_ROOT;
-                case RootPAProvisioningIntents.CREATING_ROOT_CONTAINER:
-                    return 4; //C_CREATING_ROOT_CONTAINER;
-                case RootPAProvisioningIntents.CREATING_SP_CONTAINER:
-                    return 5; //C_CREATING_SP_CONTAINER;
-                case RootPAProvisioningIntents.FINISHED_PROVISIONING:
-                    return 6; //C_FINISHED_PROVISIONING;
-                default:
-                    return 0;
-            }
-        }
-        
-        private boolean testDoProvisioning(List<String> stringList){
-            return testDoProvisioning(stringList, false);
-        }
-        
-        private boolean testDoProvisioning(List<String> stringList, boolean embeddedInOtherTest){
-            TEST_SPID = new SPID(8);
-            String logi=new String();
-            boolean overallsuccess=true;
-            CommandResult ret=new CommandResult(0xFFFF0000);
-            for(int i=0; i<intentsReceived_.length; i++) intentsReceived_[i]=false;
-
-        // set receiver for intents
-        
-            android.os.HandlerThread handlerThread = new android.os.HandlerThread("intentReceiverThread");
-            handlerThread.start();
-            android.os.Looper looper = handlerThread.getLooper();
-            android.os.Handler handler= new android.os.Handler(looper);
-
-            BroadcastReceiver receiver=new BroadcastReceiver(){
-                public void onReceive(Context ctx, Intent intent){
-                    int status = intent.getIntExtra(RootPAProvisioningIntents.STATE, 0);
-                    Log.d(TAG, "Received status intent: "+status);
-                    markIntentReceived( statusToIndex(status));
-                }
-            };
-            IntentFilter filter=new IntentFilter(RootPAProvisioningIntents.PROVISIONING_PROGRESS_UPDATE);
-            registerReceiver(receiver, filter, null, handler);
-
-            BroadcastReceiver endReceiver=new BroadcastReceiver(){
-                public void onReceive(Context ctx, Intent intent){
-                    Log.d(TAG, "Received finished intent");
-                    markIntentReceived(0);
-                }            
-            };
-            IntentFilter endFilter=new IntentFilter(RootPAProvisioningIntents.FINISHED_ROOT_PROVISIONING);
-            registerReceiver(endReceiver, endFilter, null, handler);
-
-            BroadcastReceiver errorReceiver=new BroadcastReceiver(){
-                public void onReceive(Context ctx, Intent intent){
-                    Log.d(TAG, "Received error intent: "+intent.getIntExtra(RootPAProvisioningIntents.ERROR, 0));
-                    markIntentReceived(0);
-                }            
-            };
-            IntentFilter errorFilter=new IntentFilter(RootPAProvisioningIntents.PROVISIONING_ERROR);
-            registerReceiver(errorReceiver, errorFilter, null, handler);
-
-            try{
-                ret=provisioningServiceIfc_.doProvisioning(TEST_UID, TEST_SPID);
-            }catch(Throwable e){
-                logi = logi.concat("FAILURE: call to doProvisioning failed: " + e + "\n");
-                Log.d(TAG, ": call to doProvisioning failed: "+e);
-                ret = new CommandResult(0xFFFFFFFF);
-                overallsuccess=false;
-            }
-
-        // we need to wait until all the intents are received, otherwise the interface 
-        // is still locked when trying to execute the following tests
-            if(ret.isOk()){
-                try {
-                    int totalTime=0;
-                    while(!allIntentsReceived()){
-                        Thread.sleep(500);
-                        totalTime+=500;
-                        if(totalTime>3000){
-                            break;
-                        }
-                    }
-                    Log.d(TAG, "totalTime: "+totalTime);
-                    Thread.sleep(1000); // waiting for one more second to ensure the locks are opened for the next tests    
-                } catch (Exception e) {
-                    Log.d(TAG, "sleep failed "+e);
-                }
-            } else {
-                Log.d(TAG, "error when calling doProvisioning "+ret);
-            }
-            
-            unregisterReceiver(receiver);
-            unregisterReceiver(endReceiver);
-            unregisterReceiver(errorReceiver);
-            handlerThread.quit();
-            
-            overallsuccess=!overallsuccess?overallsuccess:allIntentsReceived();
-            overallsuccess=!overallsuccess?overallsuccess:(ret.isOk());
-
-            if(!embeddedInOtherTest)
-            {
-                logi = logi.concat("================= Results of testing doProvisioning: ").concat(((overallsuccess==true)?"SUCCESS":"FAILURE")+"\n");            
-            }
-            for(int i=0; i < 7; i++){ // 7 == number of intents to be received
-                logi = logi.concat(((intentsReceived_[i]==true)?"SUCCESS":"FAILURE")+": Testing doProvisioning, receiving intent["+i+"]\n");
-            }
-            logi = logi.concat(((ret.isOk())?"SUCCESS":"FAILURE")+": Testing doProvisioning "+((ret.isOk())?"\n":("returned: " +ret+" \n")));
-            if(!embeddedInOtherTest)
-            {                             
-                logi = logi.concat("==========================================================================\n");
-            }
-
-            if(!embeddedInOtherTest || someIntentsReceived())
-            {
-                stringList.add(logi);
-            }
-            return overallsuccess;
-        }
-       
-        private boolean testContainerStructureAndState(List<String> stringList){
-
-            final SPContainerState EXPECTED_SP_CONT_STATE=SPContainerState.SP_LOCKED;
-            final int EXPECTED_NUMBER_OF_TRUSTLETS=2;
-            final TrustletContainerState EXPECTED_TLT_CONT_STATE=TrustletContainerState.SP_LOCKED;
-            long FOURS=0x0303030304040404L;
-            long FIVES=0x0505050506060606L;
-            final UUID EXPECTED_TLT_ID=new UUID(FOURS,FIVES); //CmpTest.TLTUUID;
-
-            TEST_SPID = new SPID(8);
-            String logi=new String();
-            boolean overallsuccess=true;
-            CommandResult strRet=new CommandResult(0xFFFF0000);
-            CommandResult stRet=new CommandResult(0xFFFF0000);
-            SPContainerStructure test_structure = new SPContainerStructure();
-            SPContainerStateParcel test_state = new SPContainerStateParcel();           
-                       
-            try{
-                strRet=provisioningServiceIfc_.getSPContainerStructure(TEST_SPID, test_structure);
-            }catch(Exception e){
-                logi = logi.concat("FAILURE: call to getSPContainerStructure failed: " + e + "\n");
-                strRet = new CommandResult(0xFFFFFFFF);
-                overallsuccess=false;
-            }
-
-            try{
-                stRet=provisioningServiceIfc_.getSPContainerState(TEST_SPID, test_state);
-            }catch(Exception e){
-                logi = logi.concat("FAILURE: call to getSPContainerState failed: " + e + "\n");
-                stRet = new CommandResult(0xFFFFFFFF);
-                overallsuccess=false;
-            }
-
-            List<TrustletContainer>	trustlets = test_structure.tcList();
-            
-            overallsuccess=!overallsuccess?overallsuccess:(strRet.isOk());
-            overallsuccess=!overallsuccess?overallsuccess:(test_structure.state()==EXPECTED_SP_CONT_STATE);
-            overallsuccess=!overallsuccess?overallsuccess:(trustlets.size()==EXPECTED_NUMBER_OF_TRUSTLETS);
-
-            if(overallsuccess==true){
-            
-                overallsuccess=!overallsuccess?overallsuccess:(trustlets.get(0).state().getEnumeratedValue()==EXPECTED_TLT_CONT_STATE);
-                overallsuccess=!overallsuccess?overallsuccess:(trustlets.get(0).trustletId().compareTo(EXPECTED_TLT_ID)==0);
-                overallsuccess=!overallsuccess?overallsuccess:(trustlets.get(1).state().getEnumeratedValue()==EXPECTED_TLT_CONT_STATE);
-                overallsuccess=!overallsuccess?overallsuccess:(trustlets.get(1).trustletId().compareTo(EXPECTED_TLT_ID)==0);
-            }
-            
-            overallsuccess=!overallsuccess?overallsuccess:(stRet.isOk());
-            overallsuccess=!overallsuccess?overallsuccess:(test_state.getEnumeratedValue()==EXPECTED_SP_CONT_STATE);
-
-            logi = logi.concat("================= Results of testing container structure and state: ").concat(((overallsuccess==true)?"SUCCESS":"FAILURE")+"\n");            
-            logi = logi.concat(((strRet.isOk())?"SUCCESS":"FAILURE")+": Testing getSPContainerStructure "+((strRet.isOk())?"\n":("returned: " +strRet+" \n")));
-            logi = logi.concat(((test_structure.state()==EXPECTED_SP_CONT_STATE)?"SUCCESS":"FAILURE")+": Testing getSPContainerStructure state "+
-                   ((test_structure.state()==EXPECTED_SP_CONT_STATE)?"\n":("returned: " +test_structure.state()+" \n")));
-            logi = logi.concat(((trustlets.size()==EXPECTED_NUMBER_OF_TRUSTLETS)?"SUCCESS":"FAILURE")+": Testing getSPContainerStructure nr of trustlets "+
-                   ((trustlets.size()==EXPECTED_NUMBER_OF_TRUSTLETS)?"\n":("returned: " +trustlets.size()+" \n")));
-
-            if(trustlets.size()==EXPECTED_NUMBER_OF_TRUSTLETS){
-
-                logi = logi.concat(((trustlets.get(0).trustletId().compareTo(EXPECTED_TLT_ID)==0)?"SUCCESS":"FAILURE")+": Testing getSPContainerStructure trustlet id "+
-                       ((trustlets.get(0).trustletId().compareTo(EXPECTED_TLT_ID)==0)?"\n":("returned: " +trustlets.get(0).trustletId().toString()+" \n")));
-
-                logi = logi.concat(((trustlets.get(0).state().getEnumeratedValue()==EXPECTED_TLT_CONT_STATE)?"SUCCESS":"FAILURE")+": Testing getSPContainerStructure trustlet state "+
-                       ((trustlets.get(0).state().getEnumeratedValue()==EXPECTED_TLT_CONT_STATE)?"\n":("returned: " +trustlets.get(0).state().getEnumeratedValue()+" \n")));
-            
-                logi = logi.concat(((trustlets.get(1).trustletId().compareTo(EXPECTED_TLT_ID)==0)?"SUCCESS":"FAILURE")+": Testing getSPContainerStructure trustlet id "+
-                       ((trustlets.get(1).trustletId().compareTo(EXPECTED_TLT_ID)==0)?"\n":("returned: " +trustlets.get(1).trustletId().toString()+" \n")));
-
-                logi = logi.concat(((trustlets.get(1).state().getEnumeratedValue()==EXPECTED_TLT_CONT_STATE)?"SUCCESS":"FAILURE")+": Testing getSPContainerStructure trustlet state "+
-                       ((trustlets.get(1).state().getEnumeratedValue()==EXPECTED_TLT_CONT_STATE)?"\n":("returned: " +trustlets.get(1).state().getEnumeratedValue()+" \n")));
-            }
-
-            logi = logi.concat(((stRet.isOk())?"SUCCESS":"FAILURE")+": Testing getSPContainerState "+((stRet.isOk())?"\n":("returned: " +stRet+" \n")));            
-            logi = logi.concat(((test_state.getEnumeratedValue()==EXPECTED_SP_CONT_STATE)?"SUCCESS":"FAILURE")+": Testing getSPContainerState state "+
-                   ((test_state.getEnumeratedValue()==EXPECTED_SP_CONT_STATE)?"\n":("returned: " +test_state.getEnumeratedValue()+" \n")));
-
-            logi = logi.concat("==========================================================================\n");
-
-            stringList.add(logi);
-            return overallsuccess;
-        }
-
-        /**
-        This method does not test any additional commands but it tests the ones that were already tested, this time the emphasis being in testing
-        MobiCore session.
-        */
-        private CommandResult sessionTestCommands(List<CmpTest> testCases)
-        {
-            List<CmpCommand> commands=null;
-            List<CmpResponse> responses=null;
-
-            CommandResult res=new CommandResult(0xFFFF0000);
-            try{
-                commands=new ArrayList<CmpCommand>();
-                responses=new ArrayList<CmpResponse>();
-                for(int i=0; i<testCases.size(); i++){
-                    commands.add(testCases.get(i).createCommand());
-                    commands.get(i).setIgnoreError(false);
-                }
-            }catch(java.lang.Exception e){
-                Log.e(TAG,"FAILURE: broken test case, initializing data failed: ",e);
-            }
-
-
-            try{
-                res=provisioningServiceIfc_.executeCmpCommands(TEST_UID, commands, responses);
-            }catch(Throwable e){
-                res = new CommandResult(0xFFFFFFFF);
-                Log.e(TAG,"FAILURE: sessionTestCommands executeCmpCommands failed: " + e + "\n");
-            }           
-
-            for(int i=0; i<testCases.size(); i++){
-                try{
-                    testCases.get(i).checkResult(responses.get(i));
-                } catch(java.lang.Exception e){
-                    testCases.get(i).fail();
-                    Log.e(TAG,"sessionTestCommands checking results from test "+ testCases.get(i).id() +" failed: "+e);
-                }                   
-            }
-            return res;
-        }
-
-
-        private boolean testSessionHandling(List<String> stringList){
-            String logi=new String();
-            boolean overallsuccess=true;
-
-            try{
-                provisioningServiceIfc_.acquireLock(TEST_UID); // no checking of return value since we do not test lock here (might help in debugging though)
-            }catch(Exception e){
-                Log.d(TAG, "acquiring lock failed "+e);
-            }
-
-    // the authentication is supposed to succeed
-        
-            List<CmpTest> spAuthTestCases = CmpTest.generateSpAuth();
-            CommandResult authRes=new CommandResult(0xFFFF0000);
-            authRes=sessionTestCommands(spAuthTestCases);
-
-    // the following cases are supposed to succeed even when running in different "batch" from the actual authentication          
-            Log.d(TAG,"session tests: cmp authenticated");
-            List<CmpTest> spTestCases = CmpTest.generateSpCommandsAndAuthTerminate();
-            CommandResult spRes=new CommandResult(0xFFFF0000);
-            spRes=sessionTestCommands(spTestCases);
-    
-    // the following cases are supposed to fail since we are not authenticated
-            
-            Log.d(TAG,"session tests: cmp not authenticated");
-            List<CmpTest> nonAuthCases = CmpTest.generateSpCommandsAndAuthTerminate();
-            CommandResult nonAuthRes=new CommandResult(0xFFFF0000);
-            nonAuthRes=sessionTestCommands(nonAuthCases);
-
-    // releasing lock and acquiring it again (for the case that we may open and close session in relation to the lock)
-    
-            try{
-                provisioningServiceIfc_.releaseLock(TEST_UID); // no checking of return value since we do not test lock here (might help in debugging though)
-            }catch(Exception e){
-                Log.d(TAG, "releasing lock failed "+e);
-            }
-
-            try{
-                provisioningServiceIfc_.acquireLock(TEST_UID); // no checking of return value since we do not test lock here (might help in debugging though)
-            }catch(Exception e){
-                Log.d(TAG, "acquiring lock failed "+e);
-            }
-
-    // authenticate again
-    
-            List<CmpTest> spAuth2TestCases = CmpTest.generateSpAuth();
-            CommandResult auth2Res=new CommandResult(0xFFFF0000);
-            auth2Res=sessionTestCommands(spAuth2TestCases);
-
-    // call do provisioning (should return an error since locked)
-
-            Log.d(TAG,"session tests: doProvisioning should fail");
-            boolean failedProvisioningOk = !testDoProvisioning(stringList, true);
-
-            try{
-                provisioningServiceIfc_.releaseLock(TEST_UID); // no checking of return value since we do not test lock here (might help in debugging though)
-            }catch(Exception e){
-                Log.d(TAG, "releasing lock failed "+e);
-            }
-
-    // this is supposed to succeed since own session is created for SE
-           Log.d(TAG,"session tests: doProvisioning should succeed");
-           boolean successfullProvisioningOk=testDoProvisioning(stringList, true);
-
-    // the following cases are supposed to fail since we are not authenticated (successful doProvisioning closed the session), 
-    // unfortunately this will pass also if the execution fails seriously
-
-            try{
-                provisioningServiceIfc_.acquireLock(TEST_UID); // no checking of return value since we do not test lock here (might help in debugging though)
-            }catch(Exception e){
-                Log.d(TAG, "acquiring lock failed "+e);
-            }
-
-            Log.d(TAG,"session tests: cmp not auth after doProvisioning");
-            List<CmpTest> nonAuth2Cases = CmpTest.generateSpCommandsAndAuthTerminate();
-            CommandResult nonAuth2Res=new CommandResult(0xFFFF0000);
-            nonAuth2Res=sessionTestCommands(nonAuthCases);
-
-            try{
-                provisioningServiceIfc_.releaseLock(TEST_UID); // no checking of return value since we do not test lock here (might help in debugging though)
-            }catch(Exception e){
-                Log.d(TAG, "releasing lock failed "+e);
-            }
-            
-    // checking results
-            overallsuccess=(overallsuccess==true)?(authRes.isOk()):overallsuccess;
-            overallsuccess=(overallsuccess==true)?(spRes.isOk()):overallsuccess;
-            overallsuccess=(overallsuccess==true)?(!nonAuthRes.isOk()):overallsuccess;
-            overallsuccess=(overallsuccess==true)?(auth2Res.isOk()):overallsuccess;
-            overallsuccess=(overallsuccess==true)?failedProvisioningOk:overallsuccess;
-            overallsuccess=(overallsuccess==true)?successfullProvisioningOk:overallsuccess;
-            overallsuccess=(overallsuccess==true)?(!nonAuth2Res.isOk()):overallsuccess;
-            
-            logi = logi.concat("================= Results of testing session handling\n");
-            logi = logi.concat(((authRes.isOk())?"SUCCESS":"FAILURE")+": sp auth executeCmpCommands returned: "+authRes+"\n");
-            logi = logi.concat(((spRes.isOk())?"SUCCESS":"FAILURE")+": sp executeCmpCommands returned: "+spRes+"\n");
-            logi = logi.concat(((!nonAuthRes.isOk())?"SUCCESS":"FAILURE")+": sp nonauth executeCmpCommands returned: "+nonAuthRes+"\n");
-            logi = logi.concat(((auth2Res.isOk())?"SUCCESS":"FAILURE")+": sp auth 2 executeCmpCommands returned: "+auth2Res+"\n");
-            logi = logi.concat((failedProvisioningOk?"SUCCESS":"FAILURE")+": provisioning should fail\n");
-            logi = logi.concat((successfullProvisioningOk?"SUCCESS":"FAILURE")+": provisioning should succeed\n");
-            logi = logi.concat(((!nonAuth2Res.isOk())?"SUCCESS":"FAILURE")+": sp nonauth 2 executeCmpCommands returned: "+nonAuth2Res+"\n");
-
-            for(int i=0; i<spAuthTestCases.size(); i++){
-                logi = logi.concat(((spAuthTestCases.get(i).result_==true)?"SUCCESS":"FAILURE")+": Testing "+spAuthTestCases.get(i).id()+"\n");
-                overallsuccess=(overallsuccess==true)?spAuthTestCases.get(i).result_:overallsuccess;
-            }
-
-            for(int i=0; i<spTestCases.size(); i++){
-                logi = logi.concat(((spTestCases.get(i).result_==true)?"SUCCESS":"FAILURE")+": Testing "+spTestCases.get(i).id()+"\n");
-                overallsuccess=(overallsuccess==true)?spTestCases.get(i).result_:overallsuccess;
-            }
-
-            // expecting to fail, checking accordingly
-            for(int i=0; i<nonAuthCases.size(); i++){
-                logi = logi.concat(((nonAuthCases.get(i).result_==false)?"SUCCESS":"FAILURE")+": Testing "+nonAuthCases.get(i).id()+"\n");
-                overallsuccess=(overallsuccess==true)?(nonAuthCases.get(i).result_==false):overallsuccess;
-            }
-
-            for(int i=0; i<spAuth2TestCases.size(); i++){
-                logi = logi.concat(((spAuth2TestCases.get(i).result_==true)?"SUCCESS":"FAILURE")+": Testing "+spAuth2TestCases.get(i).id()+"\n");
-                overallsuccess=(overallsuccess==true)?spAuth2TestCases.get(i).result_:overallsuccess;
-            }
-
-            // expecting to fail, checking accordingly
-            for(int i=0; i<nonAuth2Cases.size(); i++){
-                logi = logi.concat(((nonAuth2Cases.get(i).result_==false)?"SUCCESS":"FAILURE")+": Testing "+nonAuth2Cases.get(i).id()+"\n");
-                overallsuccess=(overallsuccess==true)?(nonAuth2Cases.get(i).result_==false):overallsuccess;
-            }
-
-            logi = logi.concat("==========================================================================\n");
-
-            stringList.add(logi);
-            return overallsuccess;            
-        }
-    };
-
-    private class TestOemService extends AsyncTask<IBinder, Void, Void> {
-        protected Void doInBackground(IBinder... s) {
-            IBinder service=s[0];
-            boolean res=true;
-            oemServiceIfc_= RootPAOemIfc.Stub.asInterface(service);
-            if(oemServiceIfc_ == null){
-                Log.e(TAG,"FAILURE: no oemServiceIfc_, why?");
-            }
-
-            try{
-                Log.d(TAG, "testUnregisterRootContainer");
-                res=testUnregisterRootContainer(stringList_);
-            }catch(Throwable e){
-                Log.e(TAG, "Executing testUnregisterRootContainer failed due to exception "+e);
-                res=false;
-            }
-            allTestsPassed_=(allTestsPassed_==false)?allTestsPassed_:res;
-            Log.i(TESTTAG,((res==true)?"SUCCESS":"FAILURE")+": Test testUnregisterRootContainer");
-            printFinalResults();
-            return null;
-        }
-        
-        boolean unregisterReceived_=false;
-		int unregisterError_=CommandResult.ROOTPA_OK;
-        boolean done_=false;		
-        
-        boolean testUnregisterRootContainer(List<String> stringList){
-            String logi=new String();            
-            boolean overallsuccess=true;
-            CommandResult ret=new CommandResult(0xFFFF0000);            
-
-        // set receiver for intents
-        
-            android.os.HandlerThread handlerThread = new android.os.HandlerThread("intentReceiverThread");
-            handlerThread.start();
-            android.os.Looper looper = handlerThread.getLooper();
-            android.os.Handler handler= new android.os.Handler(looper);
-
-            BroadcastReceiver errorReceiver=new BroadcastReceiver(){
-                public void onReceive(Context ctx, Intent intent){
-					unregisterError_=intent.getIntExtra(RootPAProvisioningIntents.ERROR, 0);
-                    Log.d(TAG, "Received error intent: "+intent.getIntExtra(RootPAProvisioningIntents.ERROR, unregisterError_));
-                }            
-            };
-            IntentFilter errorFilter=new IntentFilter(RootPAProvisioningIntents.PROVISIONING_ERROR);
-            registerReceiver(errorReceiver, errorFilter, null, handler);
-            
-            BroadcastReceiver statusreceiver=new BroadcastReceiver(){
-                public void onReceive(Context ctx, Intent intent){
-                    int status = intent.getIntExtra(RootPAProvisioningIntents.STATE, 0);
-                    Log.d(TAG, "Received status intent for unregister root: "+status);
-                    if(status==RootPAProvisioningIntents.FINISHED_PROVISIONING){
-                        done_=true;
-                    }else if (status==RootPAProvisioningIntents.UNREGISTERING_ROOT_CONTAINER){
-                        unregisterReceived_=true;
-                    }
-                }
-            };
-            IntentFilter statusfilter=new IntentFilter(RootPAProvisioningIntents.PROVISIONING_PROGRESS_UPDATE);
-            registerReceiver(statusreceiver, statusfilter, null, handler);
-            
-            try{
-                ret=oemServiceIfc_.unregisterRootContainer();
-            }catch(Throwable e){
-                logi = logi.concat("FAILURE: call to unregisterRootContainer failed: " + e + "\n");
-                overallsuccess=false;
-            }
-
-            if(ret.isOk()){
-                try {
-                    int totalTime=0;
-                    while(done_==false){
-
-                        Thread.sleep(500);
-                        totalTime+=500;
-                        if(totalTime>3000){
-                            break;
-                        }
-                    }
-                    Log.d(TAG, "totalTime: "+totalTime);
-//                    Thread.sleep(1000); // not waiting for one more second since this is the last test, uncomment if more tests added after this
-                } catch (Exception e) {
-                    Log.d(TAG, "sleep failed "+e);
-                }
-            }
-            else
-            {
-                Log.d(TAG, "error when calling unregisterRootContainer "+ret);                
-            }
-
-            unregisterReceiver(errorReceiver);
-            unregisterReceiver(statusreceiver);
-            handlerThread.quit();            
-
-            overallsuccess=!overallsuccess?overallsuccess:(ret.isOk());
-            overallsuccess=!overallsuccess?overallsuccess:(unregisterReceived_==true);
-            overallsuccess=!overallsuccess?overallsuccess:(unregisterError_==CommandResult.ROOTPA_OK);
-
-            logi = logi.concat("================= Results of testing unregisterRootContainer: ").concat(((overallsuccess==true)?"SUCCESS":"FAILURE")+"\n");            
-            logi = logi.concat(((ret.isOk())?"SUCCESS":"FAILURE")+": Testing unregisterRootContainer, tlt "+((ret.isOk())?"\n":("returned: " +ret+" \n")));
-            logi = logi.concat(((unregisterReceived_==true)?"SUCCESS":"FAILURE")+": Testing unregisterRootContainer, finished intent receiving\n");
-            logi = logi.concat(((unregisterError_==CommandResult.ROOTPA_OK)?"SUCCESS":"FAILURE")+": Testing unregisterRootContainer error check"+((unregisterError_==CommandResult.ROOTPA_OK)?"\n":(" error intent received: " +unregisterError_+" \n")));
-            logi = logi.concat("==========================================================================\n");
-
-            stringList.add(logi);
-            return overallsuccess;            
-        }
-    };
 }
diff --git a/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/TestDeveloperService.java b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/TestDeveloperService.java
new file mode 100755
index 0000000..0ee4848
--- /dev/null
+++ b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/TestDeveloperService.java
@@ -0,0 +1,295 @@
+/*
+Copyright  © Trustonic Limited 2013
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice, this 
+     list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright notice, 
+     this list of conditions and the following disclaimer in the documentation 
+     and/or other materials provided with the distribution.
+
+  3. Neither the name of the Trustonic Limited nor the names of its contributors 
+     may be used to endorse or promote products derived from this software 
+     without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
+OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.gd.mobicore.pa.service.Test;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.content.Intent;
+import android.os.IBinder;
+import android.content.ServiceConnection;
+import android.content.ComponentName;
+import android.content.Context;
+import android.util.Log;
+
+import android.os.AsyncTask;
+import android.os.IBinder;
+import android.content.IntentFilter;
+import android.content.BroadcastReceiver;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import com.gd.mobicore.pa.ifc.RootPAProvisioningIntents;
+import com.gd.mobicore.pa.ifc.RootPADeveloperIfc;
+import com.gd.mobicore.pa.ifc.CommandResult;
+
+class TestDeveloperService extends AsyncTask<IBinder, Void, Void> {
+    RootPADeveloperIfc developerServiceIfc_=null;
+    private static final String TESTTAG = "RootPA-Test";
+    private static final String TAG = "RootPA-T";
+    
+    RootPAClient parent_=null;
+    TestDeveloperService(RootPAClient parent){
+        super();
+        parent_=parent;
+    }
+
+    protected Void doInBackground(IBinder... s) {
+        IBinder service=s[0];
+        boolean res=true;
+        developerServiceIfc_= RootPADeveloperIfc.Stub.asInterface(service);
+        if(developerServiceIfc_ == null){
+            Log.e(TAG,"FAILURE: no developerServiceIfc_, why?");
+        }
+
+        try{
+            Log.d(TAG, "testInstallTrustlet");
+            res=testInstallTrustlet(parent_.stringList_);
+        }catch(Throwable e){
+            Log.e(TAG, "Executing testInstallTrustlet failed due to exception "+e);
+            res=false;
+        }
+        parent_.allTestsPassed_=(parent_.allTestsPassed_==false)?parent_.allTestsPassed_:res;
+        Log.i(TESTTAG,((res==true)?"SUCCESS":"FAILURE")+": Test installTrustlet");
+        
+        parent_.printFinalResults();
+        return null;
+    }
+
+    private final byte[] TEST_TRUSTLET={
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  // 200
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  // 400
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  // 600
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  // 800
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  // 1000
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  // 1200
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  // 1400
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  // 1600
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  // 1800
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  // 2000
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1  // 2200
+        };
+        
+    private final byte[] TEST_KEY={
+        1,1,1,1,1,1,1,1,1,1,            
+        2,2,2,2,2,2,2,2,2,2,
+        3,3,3,3,3,3,3,3,3,3,
+        4,4
+        };
+
+    byte[] trustlet_;
+    boolean done_=false;
+        
+    boolean testInstallTrustlet(List<String> stringList){
+        String logi=new String();            
+        boolean overallsuccess=true;
+        CommandResult tret=new CommandResult(0x0FFF0000);
+        CommandResult kret=new CommandResult(0x0FFF0000);
+        
+    // set receiver for intents
+    
+        android.os.HandlerThread handlerThread = new android.os.HandlerThread("tltIntentReceiverThread");
+
+        handlerThread.start();
+        android.os.Looper looper = handlerThread.getLooper();
+        android.os.Handler handler= new android.os.Handler(looper);
+        BroadcastReceiver receiver=new BroadcastReceiver(){
+            public void onReceive(Context ctx, Intent intent){
+                trustlet_ = intent.getByteArrayExtra(RootPAProvisioningIntents.TRUSTLET);
+                Log.d(TAG, "Received install tlt intent");
+
+            }
+        };
+        IntentFilter filter=new IntentFilter(RootPAProvisioningIntents.INSTALL_TRUSTLET);
+        parent_.registerReceiver(receiver, filter, null, handler);
+      
+        BroadcastReceiver statusreceiver=new BroadcastReceiver(){
+            public void onReceive(Context ctx, Intent intent){
+                int status = intent.getIntExtra(RootPAProvisioningIntents.STATE, 0);
+                Log.d(TAG, "Received status intent for install trustlet: "+status);
+                if(status==RootPAProvisioningIntents.FINISHED_PROVISIONING){
+                    done_=true;
+                }                        
+            }
+        };
+        IntentFilter statusfilter=new IntentFilter(RootPAProvisioningIntents.PROVISIONING_PROGRESS_UPDATE);
+        parent_.registerReceiver(statusreceiver, statusfilter, null, handler);
+
+    // installTrustlet, trustlet binary
+        
+        try{
+            tret=developerServiceIfc_.installTrustlet(TEST_TRUSTLET, null);
+        }catch(Throwable e){
+            logi = logi.concat("FAILURE: call to installTrustlet with trustlet failed: " + e + "\n");
+            overallsuccess=false;
+        }            
+
+        if(tret.isOk()){
+            try {
+                int totalTime=0;
+                while(done_==false){
+                    Thread.sleep(500);
+                    totalTime+=500;
+                    if(totalTime>6000){
+                        break;
+                    }
+                }
+                Log.d(TAG, "totalTime: "+totalTime);
+                Thread.sleep(1000); // waiting for one more second to ensure the locks are opened for the following tests    
+            } catch (Exception e) {
+                Log.d(TAG, "sleep failed "+e);
+            }
+        }
+        else
+        {
+            Log.d(TAG, "error when calling installTrustlet for tlt"+tret);                
+        }
+
+    // installTrustlet, key
+        
+        done_=false; // another call
+        try{
+            kret=developerServiceIfc_.installTrustlet(null, TEST_KEY);
+        }catch(Throwable e){
+            logi = logi.concat("FAILURE: call to installTrustlet with key failed: " + e + "\n");
+            overallsuccess=false;
+        }
+
+        if(kret.isOk()){
+            try {
+                int totalTime=0;
+                while(done_==false){
+                    Thread.sleep(500);
+                    totalTime+=500;
+                    if(totalTime>6000){
+                        break;
+                    }
+                }
+                Log.d(TAG, "totalTime: "+totalTime);
+                Thread.sleep(1000); // waiting for one more second to ensure the locks are opened for the following tests    
+            } catch (Exception e) {
+                Log.d(TAG, "sleep failed "+e);
+            }
+        }
+        else
+        {
+            Log.d(TAG, "error when calling installTrustlet for key "+kret);                
+        }            
+        
+        parent_.unregisterReceiver(receiver);
+        parent_.unregisterReceiver(statusreceiver);
+        handlerThread.quit();            
+        
+        if(trustlet_!=null){
+            boolean trustletStatus=Arrays.equals(trustlet_,TEST_TRUSTLET);
+            Log.d(TAG,"trustletStatus "+trustletStatus+" "+trustlet_.length+" "+TEST_TRUSTLET.length);
+            overallsuccess=!overallsuccess?overallsuccess:trustletStatus;
+        }else{
+            overallsuccess=false;
+        }
+        
+    // error cases
+        CommandResult err1ret=new CommandResult(0x0FFF0000);
+        try{
+            err1ret=developerServiceIfc_.installTrustlet(TEST_TRUSTLET, TEST_KEY);
+        }catch(Throwable e){
+            logi = logi.concat("FAILURE: call to installTrustlet with trustlet failed: " + e + "\n");
+            overallsuccess=false;
+        }        
+
+        CommandResult err2ret=new CommandResult(0x0FFF0000);
+        
+        try{
+            err2ret=developerServiceIfc_.installTrustlet(null, null);
+        }catch(Throwable e){
+            logi = logi.concat("FAILURE: call to installTrustlet with trustlet failed: " + e + "\n");
+            overallsuccess=false;
+        }        
+
+// results
+        
+        overallsuccess=!overallsuccess?overallsuccess:(tret.isOk());
+        overallsuccess=!overallsuccess?overallsuccess:(kret.isOk());
+        overallsuccess=!overallsuccess?overallsuccess:(err1ret.result()==CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT);
+        overallsuccess=!overallsuccess?overallsuccess:(err2ret.result()==CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT);
+        
+        logi = logi.concat("================= Results of testing installTrustlet: ").concat(((overallsuccess==true)?"SUCCESS":"FAILURE")+"\n");            
+        logi = logi.concat(((tret.isOk())?"SUCCESS":"FAILURE")+": Testing installTrustlet, tlt "+((tret.isOk())?"\n":("returned: " +tret+" \n")));
+        logi = logi.concat(((trustlet_!=null && Arrays.equals(trustlet_,TEST_TRUSTLET))?"SUCCESS":"FAILURE")+": Testing installTrustlet, tlt content in the intent\n");
+        logi = logi.concat(((kret.isOk())?"SUCCESS":"FAILURE")+": Testing installTrustlet, key "+((kret.isOk())?"\n":("returned: " +kret+" \n")));
+        logi = logi.concat(((err1ret.result()==CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT)?"SUCCESS":"FAILURE")+": Testing installTrustlet, both arguments given"+((err1ret.result()==CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT)?"\n":(", returned: " +err1ret+" \n")));
+        logi = logi.concat(((err2ret.result()==CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT)?"SUCCESS":"FAILURE")+": Testing installTrustlet, null arguments given"+((err2ret.result()==CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT)?"\n":(", returned: " +err2ret+" \n")));
+
+        logi = logi.concat("==========================================================================\n");
+
+        stringList.add(logi);
+        return overallsuccess;            
+    }
+    
+    void disconnect(){
+        developerServiceIfc_=null;    
+    }
+}
\ No newline at end of file
diff --git a/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/TestOemService.java b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/TestOemService.java
new file mode 100755
index 0000000..1d9607e
--- /dev/null
+++ b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/TestOemService.java
@@ -0,0 +1,227 @@
+/*
+Copyright  © Trustonic Limited 2013
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice, this 
+     list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright notice, 
+     this list of conditions and the following disclaimer in the documentation 
+     and/or other materials provided with the distribution.
+
+  3. Neither the name of the Trustonic Limited nor the names of its contributors 
+     may be used to endorse or promote products derived from this software 
+     without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
+OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.gd.mobicore.pa.service.Test;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.content.Intent;
+import android.os.IBinder;
+import android.content.ServiceConnection;
+import android.content.ComponentName;
+import android.content.Context;
+import android.util.Log;
+
+import android.os.AsyncTask;
+import android.os.IBinder;
+import android.content.IntentFilter;
+import android.content.BroadcastReceiver;
+
+import java.util.List;
+
+import com.gd.mobicore.pa.ifc.RootPAProvisioningIntents;
+import com.gd.mobicore.pa.ifc.RootPAOemIfc;
+import com.gd.mobicore.pa.ifc.CommandResult;
+
+class TestOemService extends AsyncTask<IBinder, Void, Void> {
+    private static final String TESTTAG = "RootPA-Test";
+    private static final String TAG = "RootPA-T";
+    
+    RootPAClient parent_=null;
+    TestOemService(RootPAClient parent){
+        super();
+        parent_=parent;
+    }
+
+    protected Void doInBackground(IBinder... s) {
+        IBinder service=s[0];
+        boolean res=true;
+        oemServiceIfc_= RootPAOemIfc.Stub.asInterface(service);
+        if(oemServiceIfc_ == null){
+            Log.e(TAG,"FAILURE: no oemServiceIfc_, why?");
+        }
+
+        try{
+            Log.d(TAG, "testUnregisterRootContainer");
+            res=testUnregisterRootContainer(parent_.stringList_, true);
+        }catch(Throwable e){
+            Log.e(TAG, "Executing testUnregisterRootContainer failed due to exception "+e);
+            res=false;
+        }
+        parent_.allTestsPassed_=(parent_.allTestsPassed_==false)?parent_.allTestsPassed_:res;
+        Log.i(TESTTAG,((res==true)?"SUCCESS":"FAILURE")+": Test testUnregisterRootContainer");
+
+        parent_.doUnbindService();
+        parent_.bindServiceWrongIp(oemServiceWrongIpConnection_);
+        return null;
+    }
+
+    
+    private ServiceConnection oemServiceWrongIpConnection_ = new ServiceConnection(){
+
+        public void onServiceDisconnected(ComponentName className){
+            oemServiceIfc_=null;
+        }
+
+        public void onServiceConnected(ComponentName className, IBinder service){
+            boolean res=true;
+            oemServiceIfc_= RootPAOemIfc.Stub.asInterface(service);
+            try{
+                Log.d(TAG, "testUnregisterRootContainer, no SE");
+                res=testUnregisterRootContainer(parent_.stringList_, false);
+            }catch(Throwable e){
+                Log.e(TAG, "Executing testUnregisterRootContainer, no SE failed due to exception "+e);
+                res=false;
+            }
+            parent_.allTestsPassed_=(parent_.allTestsPassed_==false)?parent_.allTestsPassed_:res;
+            Log.i(TESTTAG,((res==true)?"SUCCESS":"FAILURE")+": Test testUnregisterRootContainer, no SE");
+
+            parent_.unbindServiceWrongIp(oemServiceWrongIpConnection_);
+            parent_.printFinalResults();            
+        }    
+    };
+    
+    
+    private RootPAOemIfc oemServiceIfc_=null;    
+    private boolean unregisterReceived_=false;
+    private int unregisterError_=CommandResult.ROOTPA_OK;
+    private boolean done_=false;		
+    
+    boolean testUnregisterRootContainer(List<String> stringList, boolean seIpExpectedToBeToBeOk){
+        String logi=new String();            
+        boolean overallsuccess=true;
+        unregisterReceived_=false;
+        unregisterError_=CommandResult.ROOTPA_OK;
+        done_=false;		
+        
+        CommandResult ret=new CommandResult(0x0FFF0000);            
+
+    // set receiver for intents
+    
+        android.os.HandlerThread handlerThread = new android.os.HandlerThread("intentReceiverThread");
+        handlerThread.start();
+        android.os.Looper looper = handlerThread.getLooper();
+        android.os.Handler handler= new android.os.Handler(looper);
+
+        BroadcastReceiver errorReceiver=new BroadcastReceiver(){
+            public void onReceive(Context ctx, Intent intent){
+                unregisterError_=intent.getIntExtra(RootPAProvisioningIntents.ERROR, 0);
+                Log.d(TAG, "OEM: Received error intent: "+unregisterError_);
+            }            
+        };
+        IntentFilter errorFilter=new IntentFilter(RootPAProvisioningIntents.PROVISIONING_ERROR);
+        parent_.registerReceiver(errorReceiver, errorFilter, null, handler);
+        
+        BroadcastReceiver statusreceiver=new BroadcastReceiver(){
+            public void onReceive(Context ctx, Intent intent){
+                int status = intent.getIntExtra(RootPAProvisioningIntents.STATE, 0);
+                Log.d(TAG, "Received status intent for unregister root: "+status);
+                if(status==RootPAProvisioningIntents.FINISHED_PROVISIONING){
+                    done_=true;
+                }else if (status==RootPAProvisioningIntents.UNREGISTERING_ROOT_CONTAINER){
+                    unregisterReceived_=true;
+                }
+            }
+        };
+        IntentFilter statusfilter=new IntentFilter(RootPAProvisioningIntents.PROVISIONING_PROGRESS_UPDATE);
+        parent_.registerReceiver(statusreceiver, statusfilter, null, handler);
+        
+        try{
+            ret=oemServiceIfc_.unregisterRootContainer();
+        }catch(Throwable e){
+            logi = logi.concat("FAILURE: call to unregisterRootContainer failed: " + e + "\n");
+            overallsuccess=false;
+        }
+
+        if(ret.isOk()){
+            try {
+                int totalTime=0;
+                while(done_==false){
+
+                    Thread.sleep(500);
+                    totalTime+=500;
+                    if(seIpExpectedToBeToBeOk){
+                        if(totalTime>6000){
+                            break;
+                        }
+                    }else{
+                        if(totalTime>7000){ // testing connection to libcurl timeout
+                            break;
+                        }
+                    }
+                }
+                Log.d(TAG, "totalTime: "+totalTime);
+//                    Thread.sleep(1000); // not waiting for one more second since this is the last test, uncomment if more tests added after this
+            } catch (Exception e) {
+                Log.d(TAG, "sleep failed "+e);
+            }
+        }
+        else
+        {
+            Log.d(TAG, "error when calling unregisterRootContainer "+ret);                
+        }
+
+        parent_.unregisterReceiver(errorReceiver);
+        parent_.unregisterReceiver(statusreceiver);
+        handlerThread.quit();            
+
+        if(seIpExpectedToBeToBeOk)
+        {
+            overallsuccess=!overallsuccess?overallsuccess:(ret.isOk());
+            overallsuccess=!overallsuccess?overallsuccess:(unregisterReceived_==true);
+            overallsuccess=!overallsuccess?overallsuccess:(unregisterError_==CommandResult.ROOTPA_OK);
+
+            logi = logi.concat("================= Results of testing unregisterRootContainer: ").concat(((overallsuccess==true)?"SUCCESS":"FAILURE")+"\n");
+            logi = logi.concat(((ret.isOk())?"SUCCESS":"FAILURE")+": Testing unregisterRootContainer, tlt "+((ret.isOk())?"\n":("returned: " +ret+" \n")));
+            logi = logi.concat(((unregisterReceived_==true)?"SUCCESS":"FAILURE")+": Testing unregisterRootContainer, finished intent receiving\n");
+            logi = logi.concat(((unregisterError_==CommandResult.ROOTPA_OK)?"SUCCESS":"FAILURE")+": Testing unregisterRootContainer error check"+((unregisterError_==CommandResult.ROOTPA_OK)?"\n":(" error intent received: " +new CommandResult(unregisterError_)+" \n")));
+            logi = logi.concat("==========================================================================\n");
+        }
+        else
+        {
+            overallsuccess=!overallsuccess?overallsuccess:(ret.isOk());
+            overallsuccess=!overallsuccess?overallsuccess:(unregisterReceived_==false);
+            overallsuccess=!overallsuccess?overallsuccess:(unregisterError_==CommandResult.ROOTPA_ERROR_NETWORK);
+
+            logi = logi.concat("================= Results of testing unregisterRootContainer when SE is not available: ").concat(((overallsuccess==true)?"SUCCESS":"FAILURE")+"\n");
+            logi = logi.concat(((ret.isOk())?"SUCCESS":"FAILURE")+": Testing unregisterRootContainer, no SE "+((ret.isOk())?"\n":("returned: " +ret+" \n")));
+            logi = logi.concat(((unregisterReceived_==false)?"SUCCESS":"FAILURE")+": Testing unregisterRootContainer, no SE, finished intent receiving\n");
+            logi = logi.concat(((unregisterError_==CommandResult.ROOTPA_ERROR_NETWORK)?"SUCCESS":"FAILURE")+": Testing unregisterRootContainer, no SE, error check"+((unregisterError_==CommandResult.ROOTPA_ERROR_NETWORK)?"\n":(" error intent received: " +new CommandResult(unregisterError_)+" \n")));
+            logi = logi.concat("==========================================================================\n");            
+        }
+        stringList.add(logi);
+        return overallsuccess;            
+    }
+    
+    void disconnect(){
+        oemServiceIfc_=null; 
+    }
+}
\ No newline at end of file
diff --git a/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/TestProvisioningService.java b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/TestProvisioningService.java
new file mode 100755
index 0000000..c44786d
--- /dev/null
+++ b/rootpa/Test/Android/RootPAClient/src/com/gd/mobicore/pa/service/Test/TestProvisioningService.java
@@ -0,0 +1,1310 @@
+/*
+Copyright  © Trustonic Limited 2013
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright notice, this 
+     list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright notice, 
+     this list of conditions and the following disclaimer in the documentation 
+     and/or other materials provided with the distribution.
+
+  3. Neither the name of the Trustonic Limited nor the names of its contributors 
+     may be used to endorse or promote products derived from this software 
+     without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
+OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.gd.mobicore.pa.service.Test;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.content.Intent;
+import android.os.IBinder;
+import android.content.ServiceConnection;
+import android.content.ComponentName;
+import android.content.Context;
+import android.util.Log;
+
+import android.os.AsyncTask;
+import android.os.IBinder;
+import android.content.IntentFilter;
+import android.content.BroadcastReceiver;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.UUID;
+
+import com.gd.mobicore.pa.ifc.RootPAProvisioningIntents;
+import com.gd.mobicore.pa.ifc.RootPAServiceIfc;
+import com.gd.mobicore.pa.ifc.CmpMsg;
+import com.gd.mobicore.pa.ifc.CmpCommand;
+import com.gd.mobicore.pa.ifc.CmpResponse;
+import com.gd.mobicore.pa.ifc.CommandResult;
+import com.gd.mobicore.pa.ifc.BooleanResult;
+import com.gd.mobicore.pa.ifc.SPID;
+import com.gd.mobicore.pa.ifc.Version;
+import com.gd.mobicore.pa.ifc.SUID;
+import com.gd.mobicore.pa.ifc.SPContainerStructure;
+import com.gd.mobicore.pa.ifc.SPContainerStateParcel;
+import com.gd.mobicore.pa.ifc.SPContainerState;
+import com.gd.mobicore.pa.ifc.TrustletContainer;
+import com.gd.mobicore.pa.ifc.TrustletContainerState;
+
+
+class TestProvisioningService extends AsyncTask<IBinder, Void, Void> {
+    private RootPAServiceIfc provisioningServiceIfc_=null; 
+    private static final String TESTTAG = "RootPA-Test";
+    private static final String TAG = "RootPA-T";
+    private static final int TEST_SPID_VALUE=8;
+    private static final int TEST_WRONG_SPID_VALUE=12;
+    private static final int TEST_NO_TLT_SPID_VALUE=16;    
+    
+    RootPAClient parent_=null;
+    TestProvisioningService(RootPAClient parent){
+        super();
+        parent_=parent;
+    }
+    
+    protected Void doInBackground(IBinder... service) {
+        provisioningServiceIfc_= RootPAServiceIfc.Stub.asInterface(service[0]);
+        if(provisioningServiceIfc_ == null){
+            Log.e(TAG,"FAILURE: no provisioningServiceIfc_, why?");            
+        }
+
+        String s=null;
+        boolean res=true;
+
+        try{
+            Log.d(TAG, "testCmpCommands");
+            res=testCmpCommands(parent_.stringList_);
+        }catch(Throwable e){
+            Log.e(TAG, "Executing testCmpCommands failed due to exception "+e);
+            res=false;
+        }
+        parent_.allTestsPassed_=(parent_.allTestsPassed_==false)?parent_.allTestsPassed_:res;
+        Log.i(TESTTAG,"=========================================================================="); 
+        Log.i(TESTTAG,((res==true)?"SUCCESS":"FAILURE")+": Test executeCmpCommands");
+
+        try{
+            Log.d(TAG, "testRegistrationStatus");
+            res=testRegistrationStatus(parent_.stringList_);
+        }catch(Throwable e){
+            Log.e(TAG, "Executing testRegistrationStatus failed due to exception "+e);
+            res=false;
+        }
+        parent_.allTestsPassed_=(parent_.allTestsPassed_==false)?parent_.allTestsPassed_:res;
+        Log.i(TESTTAG,((res==true)?"SUCCESS":"FAILURE")+": Test isRootContainerRegistered and isSPContainerRegistered");
+
+        try{
+            Log.d(TAG, "testGetters");
+            res=testGetters(parent_.stringList_);
+        }catch(Throwable e){
+            Log.e(TAG, "Executing testGetters failed due to exception "+e);
+            res=false;
+        }
+        parent_.allTestsPassed_=(parent_.allTestsPassed_==false)?parent_.allTestsPassed_:res;
+        Log.i(TESTTAG,((res==true)?"SUCCESS":"FAILURE")+": Test getVersion and getDeviceId");
+
+        try{
+            Log.d(TAG, "testLock");
+            res=testLock(parent_.stringList_);
+        }catch(Throwable e){
+            Log.e(TAG, "Executing testLock failed due to exception "+e);
+            res=false;
+        }
+        parent_.allTestsPassed_=(parent_.allTestsPassed_==false)?parent_.allTestsPassed_:res;
+        Log.i(TESTTAG,((res==true)?"SUCCESS":"FAILURE")+": Test acquireLock and releaseLock");
+
+        try{
+            Log.d(TAG, "testDoProvisioning");
+            TEST_SPID = new SPID(TEST_SPID_VALUE);
+            res=testDoProvisioning(parent_.stringList_, TEST_SPID);
+        }catch(Throwable e){
+            Log.e(TAG, "Executing testDoProvisioning failed due to exception "+e);
+            res=false;
+        }
+        parent_.allTestsPassed_=(parent_.allTestsPassed_==false)?parent_.allTestsPassed_:res;
+        Log.i(TESTTAG,((res==true)?"SUCCESS":"FAILURE")+": Test doProvisioning");
+
+
+        try{
+            Log.d(TAG, "testDoProvisioning, errors from SE");
+            TEST_WRONG_SPID = new SPID(12); // not really wrong spid but a spid that
+            res=testDoProvisioning(parent_.stringList_, TEST_WRONG_SPID);
+        }catch(Throwable e){
+            Log.e(TAG, "Executing testDoProvisioning, errors from SE, failed due to exception "+e);
+            res=false;
+        }
+        parent_.allTestsPassed_=(parent_.allTestsPassed_==false)?parent_.allTestsPassed_:res;
+        Log.i(TESTTAG,((res==true)?"SUCCESS":"FAILURE")+": Test doProvisioning, errors from SE");
+
+        
+        try{
+            Log.d(TAG, "testContainerStructureAndState");
+            res=testContainerStructureAndState(parent_.stringList_);
+        }catch(Throwable e){
+            Log.e(TAG, "Executing testContainerStructureAndState failed due to exception "+e);
+            res=false;
+        }
+        parent_.allTestsPassed_=(parent_.allTestsPassed_==false)?parent_.allTestsPassed_:res;
+        Log.i(TESTTAG,((res==true)?"SUCCESS":"FAILURE")+": Test getSPContainerStructure and getSPContainerState");
+
+        try{
+            Log.d(TAG, "testSessionHandling");
+            res=testSessionHandling(parent_.stringList_);
+        }catch(Throwable e){
+            Log.e(TAG, "Executing testSessionHandling failed due to exception "+e);
+            res=false;
+        }
+        parent_.allTestsPassed_=(parent_.allTestsPassed_==false)?parent_.allTestsPassed_:res;
+        Log.i(TESTTAG,((res==true)?"SUCCESS":"FAILURE")+": Test session handling");
+
+        try{
+            Log.d(TAG, "test CMP error cases");
+            res=testCmpErrorCases(parent_.stringList_);
+        }catch(Throwable e){
+            Log.e(TAG, "Executing test CMP error cases failed due to exception "+e);
+            res=false;
+        }
+        parent_.allTestsPassed_=(parent_.allTestsPassed_==false)?parent_.allTestsPassed_:res;
+        Log.i(TESTTAG,((res==true)?"SUCCESS":"FAILURE")+": Test CMP error cases");
+        
+        parent_.printFinalResults();
+        return null;
+    }
+
+    public void onServiceDisconnected(ComponentName className){
+        provisioningServiceIfc_=null; 
+    }
+
+    /**
+    Test content management protocol commands
+    */
+    private boolean testCmpCommands(List<String> stringList){
+        String logi=new String();
+        CommandResult  res=new CommandResult(0x0FFF0000);
+        int uid=129;
+        List<CmpCommand> commands=null;
+        List<CmpResponse> responses=null;
+        
+        List<CmpTest> cmpTestCases = CmpTest.generateAll();
+        try{
+            commands=new ArrayList<CmpCommand>();
+            responses=new ArrayList<CmpResponse>();
+            for(int i=0; i<cmpTestCases.size(); i++){
+                commands.add(cmpTestCases.get(i).createCommand());
+                commands.get(i).setIgnoreError(true);
+            }
+        }catch(java.lang.Exception e){
+            Log.e(TAG,"FAILURE: broken test case, initializing data failed: ",e);
+        }           
+
+        try{
+            provisioningServiceIfc_.acquireLock(uid); // no checking of return value since we do not test lock here (might help in debugging though)
+            res=provisioningServiceIfc_.executeCmpCommands(uid, commands, responses);
+            provisioningServiceIfc_.releaseLock(uid); // no checking of return value since we do not test lock here (might help in debugging though)
+        }catch(Throwable e){
+            res = new CommandResult(0x0FFFFFF);
+            logi = logi.concat("FAILURE: call to executeCmpCommands failed: " + e + "\n");
+        }           
+        boolean success=true;
+        boolean overallsuccess=success;
+        
+
+        for(int i=0; i<cmpTestCases.size(); i++){
+            try{
+                cmpTestCases.get(i).checkResult(responses.get(i));
+            } catch(java.lang.Exception e){
+                Log.e(TAG,"FAILURE: checking results from test "+ cmpTestCases.get(i).id() +" failed: ",e);
+            }                   
+        }
+
+        overallsuccess=res.isOk();
+        logi = logi.concat("================= Results of testing executeCmpCommands\n");
+        logi = logi.concat(((overallsuccess==true)?"SUCCESS":"FAILURE")+": executeCmpCommands returned: "+res+"\n");
+        for(int i=0; i<cmpTestCases.size(); i++){
+            logi = logi.concat(((cmpTestCases.get(i).result_==true)?"SUCCESS":"FAILURE")+": Testing "+cmpTestCases.get(i).id()+"\n");
+            overallsuccess=(overallsuccess==true)?cmpTestCases.get(i).result_:overallsuccess;
+        }
+        logi = logi.concat("==========================================================================\n");
+        stringList.add(logi);
+        return overallsuccess;
+    }
+
+    private SPID TEST_SPID;
+    private SPID TEST_WRONG_SPID;
+    private static final int TEST_UID=0x0FFF0000;
+    private static final int TEST_UID_LOCKED=4321;
+    
+    private boolean testRegistrationStatus(List<String> stringList){
+
+        TEST_SPID = new SPID(TEST_SPID_VALUE);
+        TEST_WRONG_SPID=new SPID(TEST_WRONG_SPID_VALUE);
+        
+        String logi=new String();
+        boolean overallsuccess=true;
+
+        BooleanResult rcResult=new BooleanResult(false);
+        BooleanResult scResult=new BooleanResult(false);
+        BooleanResult scErrResult=new BooleanResult(false);        
+
+        CommandResult rcRet = new CommandResult(0x0FFF0000);
+        CommandResult scRet = new CommandResult(0x0FFF0000);
+        CommandResult scErrRet = new CommandResult(0x0FFF0000);
+        CommandResult scErr2Ret = new CommandResult(0x0FFF0000);
+        CommandResult scErr3Ret = new CommandResult(0x0FFF0000);
+        CommandResult rcErrRet = new CommandResult(0x0FFF0000);
+        
+// success cases
+        
+        try{
+            rcRet = provisioningServiceIfc_.isRootContainerRegistered(rcResult);
+        }catch(Throwable e){
+            logi = logi.concat("FAILURE: call to isRootContainerRegistered failed: " + e + "\n");
+            rcRet = new CommandResult(0x0FFFFFFF);
+            overallsuccess=false;
+        }
+
+        try{
+            scRet = provisioningServiceIfc_.isSPContainerRegistered(TEST_SPID, scResult);
+        }catch(Throwable e){
+            logi = logi.concat("FAILURE: call to isSPContainerRegistered failed: " + e + "\n");
+            scRet = new CommandResult(0x0FFFFFFF);
+            overallsuccess=false;
+        }
+
+// "error" cases
+       
+        try{
+            scErrRet = provisioningServiceIfc_.isSPContainerRegistered(TEST_WRONG_SPID, scErrResult);
+        }catch(Throwable e){
+            logi = logi.concat("FAILURE: call to isSPContainerRegistered with wrong SPID failed: " + e + "\n");
+            scErrRet = new CommandResult(0x0FFFFFFF);
+            overallsuccess=false;
+        }
+        
+        try{
+            scErr2Ret = provisioningServiceIfc_.isSPContainerRegistered(null, scErrResult);
+        }catch(Throwable e){
+            logi = logi.concat("FAILURE: call to isSPContainerRegistered with null SPID failed: " + e + "\n");
+            scErr2Ret = new CommandResult(0x0FFFFFFF);
+            overallsuccess=false;
+        }
+
+        try{
+            scErr3Ret = provisioningServiceIfc_.isSPContainerRegistered(TEST_SPID, null);
+        }catch(java.lang.NullPointerException s){
+            Log.d(TAG,"call to isSPContainerRegistered with result resulted to null pointer exception as expected\n");
+            scErr3Ret = new CommandResult(0x0FFFFFFF);
+        }catch(Throwable e){
+            logi = logi.concat("FAILURE: call to isSPContainerRegistered null data failed: " + e + "\n");
+            scErr3Ret = new CommandResult(0x0FFFFFF0);
+            overallsuccess=false;
+        }
+
+        try{
+            rcErrRet = provisioningServiceIfc_.isRootContainerRegistered(null);
+        }catch(java.lang.NullPointerException s){
+            Log.d(TAG,"call to isRootContainerRegistered with result resulted to null pointer exception as expected\n");
+            rcErrRet = new CommandResult(0x0FFFFFFF);            
+        }catch(Throwable e){
+            logi = logi.concat("FAILURE: call to isRootContainerRegistered null data failed: " + e + "\n");
+            rcErrRet = new CommandResult(0x0FFFFFF0);
+            overallsuccess=false;
+        }
+
+// result handling
+        
+        overallsuccess=!overallsuccess?overallsuccess:(rcRet.isOk());
+        overallsuccess=!overallsuccess?overallsuccess:(rcResult.result()==true);
+        overallsuccess=!overallsuccess?overallsuccess:(scRet.isOk());
+        overallsuccess=!overallsuccess?overallsuccess:(scResult.result()==true);
+
+        overallsuccess=!overallsuccess?overallsuccess:(scErrRet.isOk());
+        overallsuccess=!overallsuccess?overallsuccess:(scErrResult.result()==false);
+        
+        overallsuccess=!overallsuccess?overallsuccess:(scErr2Ret.result()==CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT);
+        overallsuccess=!overallsuccess?overallsuccess:(scErr3Ret.result()==0x0FFFFFFF);
+        overallsuccess=!overallsuccess?overallsuccess:(rcErrRet.result()==0x0FFFFFFF);
+        
+        logi = logi.concat("================= Results of testing registration status: ").concat(((overallsuccess==true)?"SUCCESS":"FAILURE")+"\n");
+        logi = logi.concat(((rcRet.isOk())?"SUCCESS":"FAILURE")+": Testing isRootContainerRegistered "+((rcRet.isOk())?"\n":("returned: " +rcRet+" \n")));
+        logi = logi.concat(((rcResult.result()==true)?"SUCCESS":"FAILURE")+": Testing isRootContainerRegistered boolean result "+((rcResult.result()==true)?"\n":("is not registered even though expected\n")));
+
+        logi = logi.concat(((scRet.isOk())?"SUCCESS":"FAILURE")+": Testing isSPContainerRegistered "+((scRet.isOk())?"\n":("returned: " +scRet+" \n")));
+        logi = logi.concat(((scResult.result()==true)?"SUCCESS":"FAILURE")+": Testing isSPContainerRegistered boolean result "+((scResult.result()==true)?"\n":("is not registered even though expected\n"))); 
+
+        logi = logi.concat(((scErrRet.isOk())?"SUCCESS":"FAILURE")+": Testing isSPContainerRegistered "+((scErrRet.isOk())?"\n":("returned: " +scErrRet+" \n")));
+        logi = logi.concat(((scErrResult.result()==false)?"SUCCESS":"FAILURE")+": Testing isSPContainerRegistered boolean result "+((scErrResult.result()==false)?"\n":("is registered even though not expected\n"))); 
+
+
+        logi = logi.concat(((scErr2Ret.result()==CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT)?"SUCCESS":"FAILURE")+": Testing isSPContainerRegistered null spid"+
+                ((scErr2Ret.result()==CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT)?"\n":(" returned: " +scErr2Ret+" \n")));
+        logi = logi.concat(((scErr3Ret.result()==0x0FFFFFFF)?"SUCCESS":"FAILURE")+": Testing isSPContainerRegistered null data"+
+                ((scErr3Ret.result()==0x0FFFFFFF)?"\n":(" returned: " +scErr3Ret+" \n")));
+        logi = logi.concat(((rcErrRet.result()==0x0FFFFFFF)?"SUCCESS":"FAILURE")+": Testing isRootContainerRegistered null data"+
+                ((rcErrRet.result()==0x0FFFFFFF)?"\n":(" returned: " +rcErrRet+" \n")));
+        
+        logi = logi.concat("==========================================================================\n");
+
+        stringList.add(logi);            
+        return overallsuccess;
+    }
+    
+    private boolean testGetters(List<String> stringList){
+
+        String logi=new String();
+        boolean overallsuccess=true;
+        CommandResult gvRet=new CommandResult(0x0FFF0000);
+        CommandResult gdiRet=new CommandResult(0x0FFF0000);
+        SUID test_suid = new SUID();
+        Version test_version = new Version();
+        final String EXPECTED_PRODUCT_ID="xxxxx";
+        final int EXPECTED_TAG=2;
+        final int EXPECTED_MCI=1;
+        final int EXPECTED_SO=2;
+        final int EXPECTED_MCLF=3;
+        final int EXPECTED_CONT=4;            
+        final int EXPECTED_MCCONF=5;
+        final int EXPECTED_TLAPI=6;
+        final int EXPECTED_DRAPI=7;
+        final int EXPECTED_CMP=8;
+
+        try{
+            gvRet=provisioningServiceIfc_.getVersion(test_version);
+        }catch(Throwable e){
+            logi = logi.concat("FAILURE: call to getVersion failed: " + e + "\n");
+            gvRet = new CommandResult(0x0FFFFFFF);
+            overallsuccess=false;
+        }
+
+        try{
+            gdiRet=provisioningServiceIfc_.getDeviceId(test_suid);        
+        }catch(Throwable e){
+            logi = logi.concat("FAILURE: call to getDeviceId failed: " + e + "\n");
+            gdiRet = new CommandResult(0x0FFFFFFF);
+            overallsuccess=false;
+        }
+
+        int tag=test_version.version().getInt("TAG");
+        int mci=test_version.version().getInt("MCI");
+        int so=test_version.version().getInt("SO");
+        int mclf=test_version.version().getInt("MCLF");
+        int cont=test_version.version().getInt("CONT");
+        int mcconf=test_version.version().getInt("MCCONF");
+        int tlapi=test_version.version().getInt("TLAPI");
+        int drapi=test_version.version().getInt("DRAPI");
+        int cmp=test_version.version().getInt("CMP");
+
+        overallsuccess=!overallsuccess?overallsuccess:(gvRet.isOk());
+        overallsuccess=!overallsuccess?overallsuccess:(test_version.productId().compareTo(EXPECTED_PRODUCT_ID)==0);
+        overallsuccess=!overallsuccess?overallsuccess:(tag==EXPECTED_TAG);
+        overallsuccess=!overallsuccess?overallsuccess:(mci==EXPECTED_MCI);
+        overallsuccess=!overallsuccess?overallsuccess:(so==EXPECTED_SO);
+        overallsuccess=!overallsuccess?overallsuccess:(mclf==EXPECTED_MCLF);
+        overallsuccess=!overallsuccess?overallsuccess:(cont==EXPECTED_CONT);            
+        overallsuccess=!overallsuccess?overallsuccess:(mcconf==EXPECTED_MCCONF);
+        overallsuccess=!overallsuccess?overallsuccess:(tlapi==EXPECTED_TLAPI);
+        overallsuccess=!overallsuccess?overallsuccess:(drapi==EXPECTED_DRAPI);                        
+        overallsuccess=!overallsuccess?overallsuccess:(cmp==EXPECTED_CMP);
+
+        overallsuccess=!overallsuccess?overallsuccess:(gdiRet.isOk());
+        overallsuccess=!overallsuccess?overallsuccess:(Arrays.equals(test_suid.suid(),CmpTest.EXPECTED_SUID));
+
+        logi = logi.concat("================= Results of testing getters: ").concat(((overallsuccess==true)?"SUCCESS":"FAILURE")+"\n");          
+        logi = logi.concat(((gvRet.isOk())?"SUCCESS":"FAILURE")+": Testing getVersion "+((gvRet.isOk())?" \n":("returned: " +gvRet+" \n")));
+        logi = logi.concat(((test_version.productId().compareTo(EXPECTED_PRODUCT_ID)==0)?"SUCCESS":"FAILURE")+": Testing getVersion, productId "+((
+                test_version.productId().compareTo(EXPECTED_PRODUCT_ID)==0)?" \n":("productId: " +test_version.productId()+" \n")));
+        logi = logi.concat(((tag==EXPECTED_TAG)?"SUCCESS":"FAILURE")+": Testing getVersion, tag"+((tag==EXPECTED_TAG)?" \n":(": " +tag+" \n")));
+        logi = logi.concat(((mci==EXPECTED_MCI)?"SUCCESS":"FAILURE")+": Testing getVersion, mci"+((mci==EXPECTED_MCI)?" \n":(": " +mci+" \n")));
+        logi = logi.concat(((so==EXPECTED_SO)?"SUCCESS":"FAILURE")+": Testing getVersion, so"+((so==EXPECTED_SO)?" \n":(": " +so+" \n")));
+        logi = logi.concat(((mclf==EXPECTED_MCLF)?"SUCCESS":"FAILURE")+": Testing getVersion, mclf"+((mclf==EXPECTED_MCLF)?" \n":(": " +mclf+" \n")));
+        logi = logi.concat(((cont==EXPECTED_CONT)?"SUCCESS":"FAILURE")+": Testing getVersion, cont"+((cont==EXPECTED_CONT)?" \n":(": " +cont+" \n")));
+        logi = logi.concat(((mcconf==EXPECTED_MCCONF)?"SUCCESS":"FAILURE")+": Testing getVersion, mcconf"+((mcconf==EXPECTED_MCCONF)?" \n":(": " +mcconf+" \n")));
+        logi = logi.concat(((tlapi==EXPECTED_TLAPI)?"SUCCESS":"FAILURE")+": Testing getVersion, tlapi"+((tlapi==EXPECTED_TLAPI)?" \n":(": " +tlapi+" \n")));
+        logi = logi.concat(((drapi==EXPECTED_DRAPI)?"SUCCESS":"FAILURE")+": Testing getVersion, drapi"+((drapi==EXPECTED_DRAPI)?" \n":(": " +drapi+" \n")));
+        logi = logi.concat(((cmp==EXPECTED_CMP)?"SUCCESS":"FAILURE")+": Testing getVersion, cmp"+((cmp==EXPECTED_CMP)?" \n":(": " +cmp+" \n")));
+
+
+        logi = logi.concat(((gdiRet.isOk())?"SUCCESS":"FAILURE")+": Testing getDeviceId "+((gdiRet.isOk())?" \n":("returned: " +gdiRet+" \n")));
+        logi = logi.concat(((Arrays.equals(test_suid.suid(),CmpTest.EXPECTED_SUID))?"SUCCESS":"FAILURE")+": Testing getDeviceId, suid "+((Arrays.equals(test_suid.suid(),CmpTest.EXPECTED_SUID))?" \n":("returned: " +CmpTest.byteArrayToDisplayable(test_suid.suid())+" \n")));
+        logi = logi.concat("==========================================================================\n");
+
+        stringList.add(logi);
+        return overallsuccess;
+    }
+
+    private boolean testLock(List<String> stringList){
+
+        String logi=new String();
+        boolean overallsuccess=true;
+        CommandResult alRet=new CommandResult(0x0FFF0000);
+        CommandResult alLockedRet=new CommandResult(0x0FFF0000);
+        CommandResult rlLockedRet=new CommandResult(0x0FFF0000);
+        CommandResult rlRet=new CommandResult(0x0FFF0000);
+        CommandResult rlOpenRet=new CommandResult(0x0FFF0000);
+
+    // first test locking when the lock is open            
+        try{
+            alRet=provisioningServiceIfc_.acquireLock(TEST_UID);
+        }catch(Throwable e){
+            logi = logi.concat("FAILURE: call to acquireLock failed: " + e + "\n");
+            alRet = new CommandResult(0x0FFFFFFF);
+            overallsuccess=false;
+        }
+
+    // then test locking when the lock is aquired 
+        try{
+            alLockedRet=provisioningServiceIfc_.acquireLock(TEST_UID_LOCKED);
+        }catch(Throwable e){
+            logi = logi.concat("FAILURE: call to acquireLock failed: " + e + "\n");
+            alLockedRet = new CommandResult(0x0FFFFFFF);
+            overallsuccess=false;
+        }
+    
+    // then test opening the lock with wrong UID when the lock is aquired 
+        try{
+            rlLockedRet=provisioningServiceIfc_.releaseLock(TEST_UID_LOCKED);        
+        }catch(Throwable e){
+            logi = logi.concat("FAILURE: call to releaseLock failed: " + e + "\n");
+            rlLockedRet = new CommandResult(0x0FFFFFFF);
+            overallsuccess=false;
+        }
+
+    // then test opening the lock when the lock is aquired 
+        try{
+            rlRet=provisioningServiceIfc_.releaseLock(TEST_UID);        
+        }catch(Throwable e){
+            logi = logi.concat("FAILURE: call to releaseLock failed: " + e + "\n");
+            rlRet = new CommandResult(0x0FFFFFFF);
+            overallsuccess=false;
+        }
+
+    // then test opening the lock when already open
+        try{
+            rlOpenRet=provisioningServiceIfc_.releaseLock(TEST_UID);        
+        }catch(Throwable e){
+            logi = logi.concat("FAILURE: call to releaseLock failed: " + e + "\n");
+            rlOpenRet = new CommandResult(0x0FFFFFFF);
+            overallsuccess=false;
+        }
+
+        overallsuccess=!overallsuccess?overallsuccess:(alRet.isOk());
+        overallsuccess=!overallsuccess?overallsuccess:(alLockedRet.result()==CommandResult.ROOTPA_ERROR_LOCK);
+        overallsuccess=!overallsuccess?overallsuccess:(rlLockedRet.result()==CommandResult.ROOTPA_ERROR_LOCK);
+        overallsuccess=!overallsuccess?overallsuccess:(rlRet.isOk());
+        overallsuccess=!overallsuccess?overallsuccess:(rlOpenRet.isOk());
+
+        logi = logi.concat("================= Results of testing lock: ").concat(((overallsuccess==true)?"SUCCESS":"FAILURE")+"\n");
+        logi = logi.concat(((alRet.isOk())?"SUCCESS":"FAILURE")+": Testing acquireLock "+((alRet.isOk())?" \n":("returned: " +alRet+" \n")));
+        logi = logi.concat(((alLockedRet.result()==CommandResult.ROOTPA_ERROR_LOCK)?"SUCCESS":"FAILURE")+": Testing acquireLock locked"+
+               ((alLockedRet.result()==CommandResult.ROOTPA_ERROR_LOCK)?" \n":("returned: " +alLockedRet+" \n")));
+
+        logi = logi.concat(((rlLockedRet.result()==CommandResult.ROOTPA_ERROR_LOCK)?"SUCCESS":"FAILURE")+": Testing releaseLock locked with different uid "+
+               ((rlLockedRet.result()==CommandResult.ROOTPA_ERROR_LOCK)?" \n":("returned: " +rlLockedRet+" \n")));
+
+        logi = logi.concat(((rlRet.isOk())?"SUCCESS":"FAILURE")+": Testing releaseLock "+((rlRet.isOk())?" \n":("returned: " +rlRet+" \n")));            
+        logi = logi.concat(((rlOpenRet.isOk())?"SUCCESS":"FAILURE")+": Testing releaseLock already open "+((rlOpenRet.isOk())?" \n":("returned: " +rlOpenRet+" \n")));            
+        logi = logi.concat("==========================================================================\n");
+
+        stringList.add(logi);
+        return overallsuccess;
+    }
+
+    final boolean[] intentsReceived_=new boolean[7]; // 7 == number of intents to be received
+    final CommandResult intentError_=new CommandResult(CommandResult.ROOTPA_OK);
+    private synchronized boolean allIntentsReceived(){
+        return (intentsReceived_[0] && intentsReceived_[1] && intentsReceived_[2] && intentsReceived_[3] && intentsReceived_[4] && intentsReceived_[5] && intentsReceived_[6]);
+    }
+
+    private boolean someIntentsReceived(){
+        return (intentsReceived_[0] ^ intentsReceived_[1] ^ intentsReceived_[2] ^ intentsReceived_[3] ^ intentsReceived_[4] ^ intentsReceived_[5] ^ intentsReceived_[6]);
+    }
+    
+    private boolean seErrorIntentsReceived(){
+        return (intentsReceived_[0] && intentsReceived_[1] && !intentsReceived_[2] && !intentsReceived_[3] && intentsReceived_[4] && !intentsReceived_[5] && !intentsReceived_[6]);
+    }
+    
+    private synchronized void markIntentReceived(int i){
+        intentsReceived_[i]=true;
+    }
+
+    private int statusToIndex(int status){
+        switch (status){
+            case RootPAProvisioningIntents.CONNECTING_SERVICE_ENABLER:
+                return 1; //C_CONNECTING_SERVICE_ENABLER;
+            case RootPAProvisioningIntents.AUTHENTICATING_SOC:
+                return 2; //C_AUTHENTICATING_SOC;
+            case RootPAProvisioningIntents.AUTHENTICATING_ROOT:
+                return 3; //C_AUTHENTICATING_ROOT;
+            case RootPAProvisioningIntents.CREATING_ROOT_CONTAINER:
+                return 4; //C_CREATING_ROOT_CONTAINER;
+            case RootPAProvisioningIntents.CREATING_SP_CONTAINER:
+                return 5; //C_CREATING_SP_CONTAINER;
+            case RootPAProvisioningIntents.FINISHED_PROVISIONING:
+                return 6; //C_FINISHED_PROVISIONING;
+            default:
+                return 0;
+        }
+    }
+    
+    private boolean testDoProvisioning(List<String> stringList, SPID spid){
+        return testDoProvisioning(stringList, false, spid);
+    }
+    
+    private boolean testDoProvisioning(List<String> stringList, boolean embeddedInOtherTest, SPID spid){
+        String logi=new String();
+        boolean overallsuccess=true;
+        CommandResult ret=new CommandResult(0x0FFF0000);
+        for(int i=0; i<intentsReceived_.length; i++) intentsReceived_[i]=false;
+        intentError_.setValue(CommandResult.ROOTPA_OK);
+    // set receiver for intents
+    
+        android.os.HandlerThread handlerThread = new android.os.HandlerThread("intentReceiverThread");
+        handlerThread.start();
+        android.os.Looper looper = handlerThread.getLooper();
+        android.os.Handler handler= new android.os.Handler(looper);
+
+        BroadcastReceiver receiver=new BroadcastReceiver(){
+            public void onReceive(Context ctx, Intent intent){
+                int status = intent.getIntExtra(RootPAProvisioningIntents.STATE, 0);
+                Log.d(TAG, "Received status intent: "+status);
+                markIntentReceived( statusToIndex(status));
+            }
+        };
+        IntentFilter filter=new IntentFilter(RootPAProvisioningIntents.PROVISIONING_PROGRESS_UPDATE);
+        parent_.registerReceiver(receiver, filter, null, handler);
+
+        BroadcastReceiver endReceiver=new BroadcastReceiver(){
+            public void onReceive(Context ctx, Intent intent){
+                Log.d(TAG, "Received finished intent");
+                markIntentReceived(0);
+            }            
+        };
+        IntentFilter endFilter=new IntentFilter(RootPAProvisioningIntents.FINISHED_ROOT_PROVISIONING);
+        parent_.registerReceiver(endReceiver, endFilter, null, handler);
+
+        BroadcastReceiver errorReceiver=new BroadcastReceiver(){
+            public void onReceive(Context ctx, Intent intent){
+                intentError_.setValue(intent.getIntExtra(RootPAProvisioningIntents.ERROR, 9999));
+                Log.d(TAG, "Provisioning: Received error intent: "+intentError_);
+                markIntentReceived(0);
+            }            
+        };
+        IntentFilter errorFilter=new IntentFilter(RootPAProvisioningIntents.PROVISIONING_ERROR);
+        parent_.registerReceiver(errorReceiver, errorFilter, null, handler);
+
+        try{
+            ret=provisioningServiceIfc_.doProvisioning(TEST_UID, spid);
+        }catch(Throwable e){
+            logi = logi.concat("FAILURE: call to doProvisioning failed: " + e + "\n");
+            Log.d(TAG, ": call to doProvisioning failed: "+e);
+            ret = new CommandResult(0x0FFFFFFF);
+            overallsuccess=false;
+        }
+
+    // we need to wait until all the intents are received, otherwise the interface 
+    // is still locked when trying to execute the following tests
+        if(ret.isOk()){
+            try {
+                int totalTime=0;
+                while(!allIntentsReceived()){
+                    Thread.sleep(500);
+                    totalTime+=500;
+                    if(totalTime>6000){
+                        break;
+                    }
+                }
+                Log.d(TAG, "totalTime: "+totalTime);
+                Thread.sleep(1000); // waiting for one more second to ensure the locks are opened for the next tests    
+            } catch (Exception e) {
+                Log.d(TAG, "sleep failed "+e);
+            }
+        } else {
+            Log.d(TAG, "error when calling doProvisioning "+ret);
+        }
+        
+        parent_.unregisterReceiver(receiver);
+        parent_.unregisterReceiver(endReceiver);
+        parent_.unregisterReceiver(errorReceiver);
+        handlerThread.quit();
+        
+
+        overallsuccess=!overallsuccess?overallsuccess:(ret.isOk());
+
+        if(TEST_SPID!=null && spid==TEST_SPID){
+            overallsuccess=!overallsuccess?overallsuccess:(intentError_.isOk());
+            overallsuccess=!overallsuccess?overallsuccess:allIntentsReceived();            
+        }else{
+            overallsuccess=!overallsuccess?overallsuccess:(intentError_.result()==CommandResult.ROOTPA_COMMAND_NOT_SUPPORTED); // only the last error is sent as intent
+            overallsuccess=!overallsuccess?overallsuccess:seErrorIntentsReceived();
+        }       
+        
+        if(!embeddedInOtherTest)
+        {
+            if(TEST_SPID!=null && spid==TEST_SPID)
+            {
+                logi = logi.concat("================= Results of testing doProvisioning: ").concat(((overallsuccess==true)?"SUCCESS":"FAILURE")+"\n");
+            }
+            else
+            {
+                logi = logi.concat("================= Results of testing doProvisioning, errors from SE: ").concat(((overallsuccess==true)?"SUCCESS":"FAILURE")+"\n");
+            }
+        }
+        if(TEST_SPID!=null && spid==TEST_SPID){
+            for(int i=0; i < 7; i++){ // 7 == number of intents to be received
+                logi = logi.concat(((intentsReceived_[i]==true)?"SUCCESS":"FAILURE")+": Testing doProvisioning, receiving intent["+i+"]\n");
+            }
+            logi = logi.concat(((intentError_.isOk())?"SUCCESS":"FAILURE")+": Testing doProvisioning, intentError "+((intentError_.isOk())?"\n":("returned: " +intentError_+" \n")));            
+        }else{
+            for(int i=0; i < 7; i++){ 
+                if(0 == i || 1 == i || 4 == i ){ // in the error case not all intents are received
+                    logi = logi.concat(((intentsReceived_[i]==true)?"SUCCESS":"FAILURE")+": Testing doProvisioning, receiving intent["+i+"]\n");
+                }
+            }
+            // only the last error is sent as intent
+            logi = logi.concat(((intentError_.result()==CommandResult.ROOTPA_COMMAND_NOT_SUPPORTED)?"SUCCESS":"FAILURE")+": Testing doProvisioning, intentError "+
+                        ((intentError_.result()==CommandResult.ROOTPA_COMMAND_NOT_SUPPORTED)?"\n":("returned: " +intentError_+" \n")));
+        }
+        logi = logi.concat(((ret.isOk())?"SUCCESS":"FAILURE")+": Testing doProvisioning "+((ret.isOk())?"\n":("returned: " +ret+" \n")));
+        if(!embeddedInOtherTest)
+        {                             
+            logi = logi.concat("==========================================================================\n");
+        }
+
+        if(!embeddedInOtherTest || someIntentsReceived())
+        {
+            stringList.add(logi);
+        }
+        return overallsuccess;
+    }
+   
+    private boolean testContainerStructureAndState(List<String> stringList){
+
+        final SPContainerState EXPECTED_SP_CONT_STATE=SPContainerState.SP_LOCKED;
+        final SPContainerState EXPECTED_SP_CONT_STATE_ERR=SPContainerState.DOES_NOT_EXIST;
+        final int EXPECTED_NUMBER_OF_TRUSTLETS=2;
+        final TrustletContainerState EXPECTED_TLT_CONT_STATE=TrustletContainerState.SP_LOCKED;
+        long FOURS=0x0303030304040404L;
+        long FIVES=0x0505050506060606L;
+        final UUID EXPECTED_TLT_ID=new UUID(FOURS,FIVES); //CmpTest.TLTUUID;
+
+        TEST_SPID = new SPID(TEST_SPID_VALUE);
+        TEST_WRONG_SPID=new SPID(TEST_WRONG_SPID_VALUE);
+        SPID TEST_SPID_UNKNOWN_TLT_CONT_INDICES=new SPID(TEST_NO_TLT_SPID_VALUE);
+        String logi=new String();
+        boolean overallsuccess=true;
+        CommandResult strRet=new CommandResult(0x0FFF0000);
+        CommandResult stRet=new CommandResult(0x0FFF0000);
+        CommandResult strErrRet=new CommandResult(0x0FFF0000);
+        CommandResult stErrRet=new CommandResult(0x0FFF0000);
+        CommandResult strErr2Ret=new CommandResult(0x0FFF0000);
+        CommandResult stErr2Ret=new CommandResult(0x0FFF0000);
+        CommandResult strErr3Ret=new CommandResult(0x0FFF0000);
+        CommandResult stErr3Ret=new CommandResult(0x0FFF0000);
+        CommandResult strErr4Ret=new CommandResult(0x0FFF0000);
+
+        SPContainerStructure test_structure = new SPContainerStructure();
+        SPContainerStateParcel test_state = new SPContainerStateParcel();           
+        SPContainerStructure test_structure_2 = new SPContainerStructure();
+        SPContainerStateParcel test_state_2 = new SPContainerStateParcel();           
+        SPContainerStructure test_structure_3 = new SPContainerStructure();
+        SPContainerStateParcel test_state_3 = new SPContainerStateParcel();           
+        SPContainerStructure test_structure_4 = new SPContainerStructure();        
+
+// success cases
+        try{
+            strRet=provisioningServiceIfc_.getSPContainerStructure(TEST_SPID, test_structure);
+        }catch(Exception e){
+            logi = logi.concat("FAILURE: call to getSPContainerStructure failed: " + e + "\n");
+            strRet = new CommandResult(0x0FFFFFFF);
+            overallsuccess=false;
+        }
+
+        try{
+            stRet=provisioningServiceIfc_.getSPContainerState(TEST_SPID, test_state);
+        }catch(Exception e){
+            logi = logi.concat("FAILURE: call to getSPContainerState failed: " + e + "\n");
+            stRet = new CommandResult(0x0FFFFFFF);
+            overallsuccess=false;
+        }
+
+// "error" cases
+
+        try{
+            strErrRet=provisioningServiceIfc_.getSPContainerStructure(TEST_WRONG_SPID, test_structure_2);
+        }catch(Exception e){
+            logi = logi.concat("FAILURE: call to getSPContainerStructure with wrong SPID failed: " + e + "\n");
+            strErrRet = new CommandResult(0x0FFFFFFF);
+            overallsuccess=false;
+        }
+
+        try{
+            stErrRet=provisioningServiceIfc_.getSPContainerState(TEST_WRONG_SPID, test_state_2);
+        }catch(Exception e){
+            logi = logi.concat("FAILURE: call to getSPContainerState with wrong SPID failed: " + e + "\n");
+            stErrRet = new CommandResult(0x0FFFFFFF);
+            overallsuccess=false;
+        }
+
+        try{
+            strErr2Ret=provisioningServiceIfc_.getSPContainerStructure(TEST_SPID, null);
+        }catch(java.lang.NullPointerException s){
+            Log.d(TAG,"call to getSPContainerStructure with null state resulted to null pointer exception as expected\n");
+            strErr2Ret = new CommandResult(0x0FFFFFFF);            
+        }catch(Exception e){
+            logi = logi.concat("FAILURE: call to getSPContainerStructure with null structure failed: " + e + "\n");
+            strErr2Ret = new CommandResult(0x0FFFFFF0);
+            overallsuccess=false;
+        }
+
+        try{
+            stErr2Ret=provisioningServiceIfc_.getSPContainerState(TEST_SPID, null);
+        }catch(java.lang.NullPointerException s){
+            Log.d(TAG,"call to getSPContainerState with null state resulted to null pointer exception as expected\n");
+            stErr2Ret = new CommandResult(0x0FFFFFFF);            
+        }catch(Exception e){
+            logi = logi.concat("FAILURE: call to getSPContainerState with null state failed: " + e + "\n");
+            stErr2Ret = new CommandResult(0x0FFFFFF0);
+            overallsuccess=false;
+        }
+
+        try{
+            strErr3Ret=provisioningServiceIfc_.getSPContainerStructure(null, test_structure_3);
+        }catch(Exception e){
+            logi = logi.concat("FAILURE: call to getSPContainerStructure with null SPID failed: " + e + "\n");
+            strErr3Ret = new CommandResult(0x0FFFFFFF);
+            overallsuccess=false;
+        }
+
+        try{
+            stErr3Ret=provisioningServiceIfc_.getSPContainerState(null, test_state_3);
+        }catch(Exception e){
+            logi = logi.concat("FAILURE: call to getSPContainerState with null SPID failed: " + e + "\n");
+            stErr3Ret = new CommandResult(0x0FFFFFFF);
+            overallsuccess=false;
+        }
+
+
+        try{
+            strErr4Ret=provisioningServiceIfc_.getSPContainerStructure(TEST_SPID_UNKNOWN_TLT_CONT_INDICES, test_structure_4);
+        }catch(Exception e){
+            logi = logi.concat("FAILURE: call to getSPContainerStructure where sp container points to missing tlt containers failed: " + e + "\n");
+            strErr4Ret = new CommandResult(0x0FFFFFFF);
+            overallsuccess=false;
+        }
+        
+    
+        
+        List<TrustletContainer>	trustlets = test_structure.tcList();
+        
+        overallsuccess=!overallsuccess?overallsuccess:(strRet.isOk());
+        overallsuccess=!overallsuccess?overallsuccess:(test_structure.state()==EXPECTED_SP_CONT_STATE);
+        overallsuccess=!overallsuccess?overallsuccess:(trustlets.size()==EXPECTED_NUMBER_OF_TRUSTLETS);
+
+        
+        if(overallsuccess==true){
+        
+            overallsuccess=!overallsuccess?overallsuccess:(trustlets.get(0).state().getEnumeratedValue()==EXPECTED_TLT_CONT_STATE);
+            overallsuccess=!overallsuccess?overallsuccess:(trustlets.get(0).trustletId().compareTo(EXPECTED_TLT_ID)==0);
+            overallsuccess=!overallsuccess?overallsuccess:(trustlets.get(1).state().getEnumeratedValue()==EXPECTED_TLT_CONT_STATE);
+            overallsuccess=!overallsuccess?overallsuccess:(trustlets.get(1).trustletId().compareTo(EXPECTED_TLT_ID)==0);
+        }
+        
+        overallsuccess=!overallsuccess?overallsuccess:(stRet.isOk());
+        overallsuccess=!overallsuccess?overallsuccess:(test_state.getEnumeratedValue()==EXPECTED_SP_CONT_STATE);
+        
+        overallsuccess=!overallsuccess?overallsuccess:(strErrRet.isOk());
+        overallsuccess=!overallsuccess?overallsuccess:(stErrRet.isOk());
+        overallsuccess=!overallsuccess?overallsuccess:(test_structure_2.state()==EXPECTED_SP_CONT_STATE_ERR);
+        overallsuccess=!overallsuccess?overallsuccess:(test_state_2.getEnumeratedValue()==EXPECTED_SP_CONT_STATE_ERR);               
+        overallsuccess=!overallsuccess?overallsuccess:(strErr2Ret.result()==0x0FFFFFFF); // null pointer exception received
+        overallsuccess=!overallsuccess?overallsuccess:(stErr2Ret.result()==0x0FFFFFFF); // null pointer exception received
+        overallsuccess=!overallsuccess?overallsuccess:(strErr3Ret.result()==CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT);
+        overallsuccess=!overallsuccess?overallsuccess:(stErr3Ret.result()==CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT);
+        overallsuccess=!overallsuccess?overallsuccess:(strErr4Ret.result()==CommandResult.ROOTPA_ERROR_REGISTRY);
+        
+        logi = logi.concat("================= Results of testing container structure and state: ").concat(((overallsuccess==true)?"SUCCESS":"FAILURE")+"\n");            
+        logi = logi.concat(((strRet.isOk())?"SUCCESS":"FAILURE")+": Testing getSPContainerStructure "+((strRet.isOk())?"\n":("returned: " +strRet+" \n")));
+        logi = logi.concat(((test_structure.state()==EXPECTED_SP_CONT_STATE)?"SUCCESS":"FAILURE")+": Testing getSPContainerStructure state "+
+               ((test_structure.state()==EXPECTED_SP_CONT_STATE)?"\n":("returned: " +test_structure.state()+" \n")));
+        logi = logi.concat(((trustlets.size()==EXPECTED_NUMBER_OF_TRUSTLETS)?"SUCCESS":"FAILURE")+": Testing getSPContainerStructure nr of trustlets "+
+               ((trustlets.size()==EXPECTED_NUMBER_OF_TRUSTLETS)?"\n":("returned: " +trustlets.size()+" \n")));
+
+        if(trustlets.size()==EXPECTED_NUMBER_OF_TRUSTLETS){
+
+            logi = logi.concat(((trustlets.get(0).trustletId().compareTo(EXPECTED_TLT_ID)==0)?"SUCCESS":"FAILURE")+": Testing getSPContainerStructure trustlet id "+
+                   ((trustlets.get(0).trustletId().compareTo(EXPECTED_TLT_ID)==0)?"\n":("returned: " +trustlets.get(0).trustletId().toString()+" \n")));
+
+            logi = logi.concat(((trustlets.get(0).state().getEnumeratedValue()==EXPECTED_TLT_CONT_STATE)?"SUCCESS":"FAILURE")+": Testing getSPContainerStructure trustlet state "+
+                   ((trustlets.get(0).state().getEnumeratedValue()==EXPECTED_TLT_CONT_STATE)?"\n":("returned: " +trustlets.get(0).state().getEnumeratedValue()+" \n")));
+        
+            logi = logi.concat(((trustlets.get(1).trustletId().compareTo(EXPECTED_TLT_ID)==0)?"SUCCESS":"FAILURE")+": Testing getSPContainerStructure trustlet id "+
+                   ((trustlets.get(1).trustletId().compareTo(EXPECTED_TLT_ID)==0)?"\n":("returned: " +trustlets.get(1).trustletId().toString()+" \n")));
+
+            logi = logi.concat(((trustlets.get(1).state().getEnumeratedValue()==EXPECTED_TLT_CONT_STATE)?"SUCCESS":"FAILURE")+": Testing getSPContainerStructure trustlet state "+
+                   ((trustlets.get(1).state().getEnumeratedValue()==EXPECTED_TLT_CONT_STATE)?"\n":("returned: " +trustlets.get(1).state().getEnumeratedValue()+" \n")));
+        }
+
+        logi = logi.concat(((stRet.isOk())?"SUCCESS":"FAILURE")+": Testing getSPContainerState "+((stRet.isOk())?"\n":("returned: " +stRet+" \n")));
+        logi = logi.concat(((test_state.getEnumeratedValue()==EXPECTED_SP_CONT_STATE)?"SUCCESS":"FAILURE")+": Testing getSPContainerState state "+
+               ((test_state.getEnumeratedValue()==EXPECTED_SP_CONT_STATE)?"\n":("returned: " +test_state.getEnumeratedValue()+" \n")));
+
+        
+        logi = logi.concat(((strErrRet.isOk())?"SUCCESS":"FAILURE")+": Testing getSPContainerStructure wrong SPID"+
+                ((strErrRet.isOk())?"\n":(" returned: " +strErrRet+" \n")));
+        logi = logi.concat(((stErrRet.isOk())?"SUCCESS":"FAILURE")+": Testing getSPContainerState wrong SPID"+
+                ((stErrRet.isOk())?"\n":(" returned: " +stErrRet+" \n")));
+                
+        logi = logi.concat(((test_structure.state()==EXPECTED_SP_CONT_STATE)?"SUCCESS":"FAILURE")+": Testing getSPContainerStructure state, nonexitent "+
+               ((test_structure_2.state()==EXPECTED_SP_CONT_STATE_ERR)?"\n":("returned: " +test_structure_2.state()+" \n")));
+
+        logi = logi.concat(((test_state_2.getEnumeratedValue()==EXPECTED_SP_CONT_STATE_ERR)?"SUCCESS":"FAILURE")+": Testing getSPContainerState state, nonexistent "+
+               ((test_state_2.getEnumeratedValue()==EXPECTED_SP_CONT_STATE_ERR)?"\n":("returned: " +test_state_2.getEnumeratedValue()+" \n")));
+
+        
+        logi = logi.concat(((strErr2Ret.result()==0x0FFFFFFF)?"SUCCESS":"FAILURE")+": Testing getSPContainerStructure null data"+
+                ((strErr2Ret.result()==0x0FFFFFFF)?"\n":(" returned: " +strErr2Ret+" \n")));
+        logi = logi.concat(((stErr2Ret.result()==0x0FFFFFFF)?"SUCCESS":"FAILURE")+": Testing getSPContainerState null data"+
+                ((stErr2Ret.result()==0x0FFFFFFF)?"\n":(" returned: " +stErr2Ret+" \n")));  
+        logi = logi.concat(((strErr3Ret.result()==CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT)?"SUCCESS":"FAILURE")+": Testing getSPContainerStructure null SPID "+
+                ((strErr3Ret.result()==CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT)?"\n":(" returned: " +strErr3Ret+" \n")));
+        logi = logi.concat(((stErr3Ret.result()==CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT)?"SUCCESS":"FAILURE")+": Testing getSPContainerState null SPID"+
+                ((stErr3Ret.result()==CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT)?"\n":(" returned: " +stErr3Ret+" \n")));
+
+        logi = logi.concat(((strErr4Ret.result()==CommandResult.ROOTPA_ERROR_REGISTRY)?"SUCCESS":"FAILURE")+": Testing getSPContainerStructure, sp cont points to missing tlt cont's "+
+                ((strErr4Ret.result()==CommandResult.ROOTPA_ERROR_REGISTRY)?"\n":(" returned: " +strErr4Ret+" \n")));
+
+
+        logi = logi.concat("==========================================================================\n");
+
+        stringList.add(logi);
+        return overallsuccess;
+    }
+
+    /**
+    This method does not test any additional commands but it tests the ones that were already tested, this time the emphasis being in testing
+    MobiCore session.
+    */
+    private CommandResult sessionTestCommands(List<CmpTest> testCases, boolean ignoreError)
+    {
+        List<CmpCommand> commands=null;
+        List<CmpResponse> responses=null;
+
+        CommandResult res=new CommandResult(0x0FFF0000);
+        try{
+            commands=new ArrayList<CmpCommand>();
+            responses=new ArrayList<CmpResponse>();
+            for(int i=0; i<testCases.size(); i++){
+                commands.add(testCases.get(i).createCommand());
+                commands.get(i).setIgnoreError(ignoreError);
+            }
+        }catch(java.lang.Exception e){
+            Log.e(TAG,"FAILURE: broken test case, initializing data failed: ",e);
+        }
+
+
+        try{
+            res=provisioningServiceIfc_.executeCmpCommands(TEST_UID, commands, responses);
+        }catch(Throwable e){
+            res = new CommandResult(0x0FFFFFFF);
+            Log.e(TAG,"FAILURE: sessionTestCommands executeCmpCommands failed: " + e + "\n");
+        }           
+
+        for(int i=0; i<testCases.size(); i++){
+            try{
+                testCases.get(i).checkResult(responses.get(i));
+            } catch(java.lang.Exception e){
+                testCases.get(i).fail();
+                Log.e(TAG,"sessionTestCommands checking results from test "+ testCases.get(i).id() +" failed: "+e);
+            }                   
+        }
+        return res;
+    }
+
+
+    private boolean testSessionHandling(List<String> stringList){
+        String logi=new String();
+        boolean overallsuccess=true;
+        TEST_SPID = new SPID(TEST_SPID_VALUE);
+
+        try{
+            provisioningServiceIfc_.acquireLock(TEST_UID); // no checking of return value since we do not test lock here (might help in debugging though)
+        }catch(Exception e){
+            Log.d(TAG, "acquiring lock failed "+e);
+        }
+
+// the authentication is supposed to succeed
+    
+        List<CmpTest> spAuthTestCases = CmpTest.generateSpAuth();
+        CommandResult authRes=new CommandResult(0x0FFF0000);
+        authRes=sessionTestCommands(spAuthTestCases, false);
+
+// the following cases are supposed to succeed even when running in different "batch" from the actual authentication          
+        Log.d(TAG,"session tests: cmp authenticated");
+        List<CmpTest> spTestCases = CmpTest.generateSpCommandsAndAuthTerminate();
+        CommandResult spRes=new CommandResult(0x0FFF0000);
+        spRes=sessionTestCommands(spTestCases, false);
+
+// the following cases are supposed to fail since we are not authenticated
+        
+        Log.d(TAG,"session tests: cmp not authenticated");  // this also test running multiple commands when ignoreError is false and one of the tests fail
+        List<CmpTest> nonAuthCases = CmpTest.generateSpCommandsAndAuthTerminate();
+        CommandResult nonAuthRes=new CommandResult(0x0FFF0000);
+        nonAuthRes=sessionTestCommands(nonAuthCases, false);
+
+// releasing lock and acquiring it again (for the case that we may open and close session in relation to the lock)
+
+        try{
+            provisioningServiceIfc_.releaseLock(TEST_UID); // no checking of return value since we do not test lock here (might help in debugging though)
+        }catch(Exception e){
+            Log.d(TAG, "releasing lock failed "+e);
+        }
+
+        try{
+            provisioningServiceIfc_.acquireLock(TEST_UID); // no checking of return value since we do not test lock here (might help in debugging though)
+        }catch(Exception e){
+            Log.d(TAG, "acquiring lock failed "+e);
+        }
+
+// authenticate again
+
+        List<CmpTest> spAuth2TestCases = CmpTest.generateSpAuth();
+        CommandResult auth2Res=new CommandResult(0x0FFF0000);
+        auth2Res=sessionTestCommands(spAuth2TestCases, false);
+
+// call do provisioning (should return an error since locked)
+
+        Log.d(TAG,"session tests: doProvisioning should fail");
+        boolean failedProvisioningOk = !testDoProvisioning(stringList, true, TEST_SPID);
+
+        try{
+            provisioningServiceIfc_.releaseLock(TEST_UID); // no checking of return value since we do not test lock here (might help in debugging though)
+        }catch(Exception e){
+            Log.d(TAG, "releasing lock failed "+e);
+        }
+
+// this is supposed to succeed since own session is created for SE
+       Log.d(TAG,"session tests: doProvisioning should succeed");
+       List<String> stringListProvisioning = new ArrayList<String>();
+       boolean successfullProvisioningOk=testDoProvisioning(stringListProvisioning, true, TEST_SPID);
+
+// the following cases are supposed to fail since we are not authenticated (successful doProvisioning closed the session), 
+// unfortunately this will pass also if the execution fails seriously
+
+        try{
+            provisioningServiceIfc_.acquireLock(TEST_UID); // no checking of return value since we do not test lock here (might help in debugging though)
+        }catch(Exception e){
+            Log.d(TAG, "acquiring lock failed "+e);
+        }
+
+        Log.d(TAG,"session tests: cmp not auth after doProvisioning");  // this also test running multiple commands when ignoreError is true and one of the tests fail
+        List<CmpTest> nonAuth2Cases = CmpTest.generateSpCommandsAndAuthTerminate();
+        CommandResult nonAuth2Res=new CommandResult(0x0FFF0000);
+        nonAuth2Res=sessionTestCommands(nonAuthCases, true);
+
+        try{
+            provisioningServiceIfc_.releaseLock(TEST_UID); // no checking of return value since we do not test lock here (might help in debugging though)
+        }catch(Exception e){
+            Log.d(TAG, "releasing lock failed "+e);
+        }
+        
+// checking results
+        overallsuccess=(overallsuccess==true)?(authRes.isOk()):overallsuccess;
+        overallsuccess=(overallsuccess==true)?(spRes.isOk()):overallsuccess;
+        overallsuccess=(overallsuccess==true)?(!nonAuthRes.isOk()):overallsuccess;
+        overallsuccess=(overallsuccess==true)?(auth2Res.isOk()):overallsuccess;
+        overallsuccess=(overallsuccess==true)?failedProvisioningOk:overallsuccess;
+        overallsuccess=(overallsuccess==true)?successfullProvisioningOk:overallsuccess;
+        overallsuccess=(overallsuccess==true)?(!nonAuth2Res.isOk()):overallsuccess;
+        
+        logi = logi.concat("================= Results of testing session handling\n");
+        logi = logi.concat(((authRes.isOk())?"SUCCESS":"FAILURE")+": sp auth executeCmpCommands returned: "+authRes+"\n");
+        logi = logi.concat(((spRes.isOk())?"SUCCESS":"FAILURE")+": sp executeCmpCommands returned: "+spRes+"\n");
+        logi = logi.concat(((!nonAuthRes.isOk())?"SUCCESS":"FAILURE")+": sp nonauth executeCmpCommands returned: "+nonAuthRes+"\n");
+        logi = logi.concat(((auth2Res.isOk())?"SUCCESS":"FAILURE")+": sp auth 2 executeCmpCommands returned: "+auth2Res+"\n");
+        logi = logi.concat((failedProvisioningOk?"SUCCESS":"FAILURE")+": provisioning should fail\n");
+        logi = logi.concat((successfullProvisioningOk?"SUCCESS":"FAILURE")+": provisioning should succeed\n");
+        String logi2=new String();
+        
+        logi2 = logi2.concat(((!nonAuth2Res.isOk())?"SUCCESS":"FAILURE")+": sp nonauth 2 executeCmpCommands returned: "+nonAuth2Res+"\n");
+
+        for(int i=0; i<spAuthTestCases.size(); i++){
+            logi2 = logi2.concat(((spAuthTestCases.get(i).result_==true)?"SUCCESS":"FAILURE")+": Testing "+spAuthTestCases.get(i).id()+"\n");
+            overallsuccess=(overallsuccess==true)?spAuthTestCases.get(i).result_:overallsuccess;
+        }
+
+        for(int i=0; i<spTestCases.size(); i++){
+            logi2 = logi2.concat(((spTestCases.get(i).result_==true)?"SUCCESS":"FAILURE")+": Testing "+spTestCases.get(i).id()+"\n");
+            overallsuccess=(overallsuccess==true)?spTestCases.get(i).result_:overallsuccess;
+        }
+
+        // expecting to fail, checking accordingly
+        for(int i=0; i<nonAuthCases.size(); i++){
+            logi2 = logi2.concat(((nonAuthCases.get(i).result_==false)?"SUCCESS":"FAILURE")+": Testing "+nonAuthCases.get(i).id()+"\n");
+            overallsuccess=(overallsuccess==true)?(nonAuthCases.get(i).result_==false):overallsuccess;
+        }
+
+        for(int i=0; i<spAuth2TestCases.size(); i++){
+            logi2 = logi2.concat(((spAuth2TestCases.get(i).result_==true)?"SUCCESS":"FAILURE")+": Testing "+spAuth2TestCases.get(i).id()+"\n");
+            overallsuccess=(overallsuccess==true)?spAuth2TestCases.get(i).result_:overallsuccess;
+        }
+
+        // expecting to fail, checking accordingly
+        for(int i=0; i<nonAuth2Cases.size(); i++){
+            logi2 = logi2.concat(((nonAuth2Cases.get(i).result_==false)?"SUCCESS":"FAILURE")+": Testing "+nonAuth2Cases.get(i).id()+"\n");
+            overallsuccess=(overallsuccess==true)?(nonAuth2Cases.get(i).result_==false):overallsuccess;
+        }
+
+        logi2 = logi2.concat("==========================================================================\n");
+
+        stringList.add(logi);
+        stringList.addAll(stringListProvisioning);
+        stringList.add(logi2);        
+        return overallsuccess;            
+    }
+    
+    /**
+    Test content management protocol commands with error cases
+    */
+    private boolean testCmpErrorCases(List<String> stringList){
+        String logi=new String();
+        CommandResult  res=new CommandResult(0x0FFF0000);
+        CommandResult  nocontainerres=new CommandResult(0x0FFF0000);
+        CommandResult  nostorecontainerres=new CommandResult(0x0FFF0000);
+        CommandResult  responseerrorres=new CommandResult(0x0FFF0000);
+        CommandResult  nullcres=new CommandResult(0x0FFF0000);
+        CommandResult  nullrres=new CommandResult(0x0FFF0000);
+
+        int uid=129;
+        List<CmpCommand> commands=null;
+        List<CmpResponse> responses=null;
+
+// error commands
+        Log.i(TAG,"q: error commands ");
+        
+        List<CmpTest> cmpTestCases = CmpTest.generateErrorCases();
+        try{
+            commands=new ArrayList<CmpCommand>();
+            responses=new ArrayList<CmpResponse>();
+            for(int i=0; i<cmpTestCases.size(); i++){
+                commands.add(cmpTestCases.get(i).createCommand());
+                commands.get(i).setIgnoreError(true);
+            }
+        }catch(java.lang.Exception e){
+            Log.e(TAG,"FAILURE: broken test case, initializing data failed: ",e);
+        }           
+
+        try{
+            provisioningServiceIfc_.acquireLock(uid); // no checking of return value since we do not test lock here (might help in debugging though)
+            res=provisioningServiceIfc_.executeCmpCommands(uid, commands, responses);
+            provisioningServiceIfc_.releaseLock(uid); // no checking of return value since we do not test lock here (might help in debugging though)
+        }catch(Throwable e){
+            res = new CommandResult(0x0FFFFFFF);
+            logi = logi.concat("FAILURE: call to executeCmpCommands failed: " + e + "\n");
+        }           
+
+        for(int i=0; i<cmpTestCases.size(); i++){
+            try{
+                cmpTestCases.get(i).checkResult(responses.get(i));
+            } catch(java.lang.Exception e){
+                Log.e(TAG,"FAILURE: checking results from test "+ cmpTestCases.get(i).id() +" failed: ",e);
+            }                   
+        }
+
+// no container 
+        Log.i(TAG,"testCmpErrorCases: no container ");        
+
+        List<CmpTest> cmpNoContainerCases = CmpTest.generateNoContainerCases();
+        try{
+            commands=new ArrayList<CmpCommand>();
+            responses=new ArrayList<CmpResponse>();
+            for(int i=0; i<cmpNoContainerCases.size(); i++){
+                commands.add(cmpNoContainerCases.get(i).createCommand());
+                commands.get(i).setIgnoreError(true);
+            }
+        }catch(java.lang.Exception e){
+            Log.e(TAG,"FAILURE: broken no container test case, initializing data failed: ",e);
+        }           
+
+        try{
+            provisioningServiceIfc_.acquireLock(uid); // no checking of return value since we do not test lock here (might help in debugging though)
+            nocontainerres=provisioningServiceIfc_.executeCmpCommands(uid, commands, responses);
+            provisioningServiceIfc_.releaseLock(uid); // no checking of return value since we do not test lock here (might help in debugging though)
+        }catch(Throwable e){
+            nocontainerres = new CommandResult(0x0FFFFFFF);
+            logi = logi.concat("FAILURE: call to executeCmpCommands failed: " + e + "\n");
+        }           
+
+
+        for(int i=0; i<cmpNoContainerCases.size(); i++){
+            try{
+                cmpNoContainerCases.get(i).checkResult(responses.get(i));
+            } catch(java.lang.Exception e){
+                Log.e(TAG,"FAILURE: checking results from test "+ cmpNoContainerCases.get(i).id() +" failed: ",e);
+            }                   
+        }
+// can not store container generateNoStoreContainerCases        
+
+        Log.i(TAG,"testCmpErrorCases: can not store container ");        
+
+        List<CmpTest> cmpNoStoreContainerCases = CmpTest.generateNoStoreContainerCases();
+        try{
+            commands=new ArrayList<CmpCommand>();
+            responses=new ArrayList<CmpResponse>();
+            for(int i=0; i<cmpNoStoreContainerCases.size(); i++){
+                commands.add(cmpNoStoreContainerCases.get(i).createCommand());
+                commands.get(i).setIgnoreError(true);
+            }
+        }catch(java.lang.Exception e){
+            Log.e(TAG,"FAILURE: broken no store container test case, initializing data failed: ",e);
+        }           
+
+        try{
+            provisioningServiceIfc_.acquireLock(uid); // no checking of return value since we do not test lock here (might help in debugging though)
+            nostorecontainerres=provisioningServiceIfc_.executeCmpCommands(uid, commands, responses);
+            provisioningServiceIfc_.releaseLock(uid); // no checking of return value since we do not test lock here (might help in debugging though)
+        }catch(Throwable e){
+            nostorecontainerres = new CommandResult(0x0FFFFFFF);
+            logi = logi.concat("FAILURE: call to executeCmpCommands failed: " + e + "\n");
+        }           
+
+
+        for(int i=0; i<cmpNoStoreContainerCases.size(); i++){
+            try{
+                cmpNoStoreContainerCases.get(i).checkResult(responses.get(i));
+            } catch(java.lang.Exception e){
+                Log.e(TAG,"FAILURE: checking results from test "+ cmpNoStoreContainerCases.get(i).id() +" failed: ",e);
+            }                   
+        }
+
+// unknown response, offsets wrong
+        
+        
+        Log.i(TAG,"testCmpErrorCases: problems in response id's or offsets ");        
+
+        List<CmpTest> cmpResponseErrorCases = CmpTest.generateResponseErrorCases();
+        try{
+            commands=new ArrayList<CmpCommand>();
+            responses=new ArrayList<CmpResponse>();
+            for(int i=0; i<cmpResponseErrorCases.size(); i++){
+                commands.add(cmpResponseErrorCases.get(i).createCommand());
+                commands.get(i).setIgnoreError(true);
+            }
+        }catch(java.lang.Exception e){
+            Log.e(TAG,"FAILURE: broken response test case, initializing data failed: ",e);
+        }           
+
+        try{
+            provisioningServiceIfc_.acquireLock(uid); // no checking of return value since we do not test lock here (might help in debugging though)
+            responseerrorres=provisioningServiceIfc_.executeCmpCommands(uid, commands, responses);
+            provisioningServiceIfc_.releaseLock(uid); // no checking of return value since we do not test lock here (might help in debugging though)
+        }catch(Throwable e){
+            responseerrorres = new CommandResult(0x0FFFFFFF);
+            logi = logi.concat("FAILURE: call to executeCmpCommands failed: " + e + "\n");
+        }           
+
+        for(int i=0; i<cmpResponseErrorCases.size(); i++){
+            try{
+                cmpResponseErrorCases.get(i).checkResult(responses.get(i));
+            } catch(java.lang.Exception e){
+                Log.e(TAG,"FAILURE: checking results from test "+ cmpResponseErrorCases.get(i).id() +" failed: ",e);
+            }                   
+        }
+        
+        
+// null parameters
+        Log.i(TAG,"testCmpErrorCases: null params ");        
+
+        try{
+            provisioningServiceIfc_.acquireLock(uid); // no checking of return value since we do not test lock here (might help in debugging though)
+            nullcres=provisioningServiceIfc_.executeCmpCommands(uid, null, responses);
+            provisioningServiceIfc_.releaseLock(uid); // no checking of return value since we do not test lock here (might help in debugging though)
+        }catch(Throwable e){
+            nullcres = new CommandResult(0x0FFFFFFF);
+            logi = logi.concat("FAILURE: call to executeCmpCommands with null commands failed: " + e + "\n");
+        }           
+
+
+        try{
+            provisioningServiceIfc_.acquireLock(uid); // no checking of return value since we do not test lock here (might help in debugging though)
+            nullrres=provisioningServiceIfc_.executeCmpCommands(uid, commands, null);
+        }catch(java.lang.NullPointerException s){
+            Log.d(TAG,"call call to executeCmpCommands with null responses resulted to null pointer exception as expected\n");
+            nullrres = new CommandResult(0x0FFFFFF0);
+            try{
+                provisioningServiceIfc_.releaseLock(uid); // no checking of return value since we do not test lock here (might help in debugging though)
+            }catch (Throwable le){
+                Log.e(TAG, "releasing lock failed "+le);
+            }
+        }catch(Throwable e){
+            nullrres = new CommandResult(0x0FFFFFFF);
+            logi = logi.concat("FAILURE: call to executeCmpCommands with null responses failed: " + e + "\n");
+        }           
+
+// check results
+        
+        boolean success=true;
+        boolean overallsuccess=success;
+        
+        overallsuccess=!overallsuccess?overallsuccess:(res.result()==CommandResult.ROOTPA_COMMAND_NOT_SUPPORTED);
+        overallsuccess=!overallsuccess?overallsuccess:(nocontainerres.result()==CommandResult.ROOTPA_ERROR_REGISTRY_OBJECT_NOT_AVAILABLE);
+        overallsuccess=!overallsuccess?overallsuccess:(nostorecontainerres.result()==CommandResult.ROOTPA_ERROR_REGISTRY);
+        overallsuccess=!overallsuccess?overallsuccess:(responseerrorres.result()==CommandResult.ROOTPA_ERROR_INTERNAL);
+        overallsuccess=!overallsuccess?overallsuccess:(nullcres.result()==CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT);
+        overallsuccess=!overallsuccess?overallsuccess:(nullrres.result()==0x0FFFFFF0);
+        
+        logi = logi.concat("================= Results of testing CMP command error cases \n");
+        logi = logi.concat(((res.result()==CommandResult.ROOTPA_COMMAND_NOT_SUPPORTED)?"SUCCESS":"FAILURE")+": executeCmpCommands (error cases) returned: "+res+"\n");
+        for(int i=0; i<cmpTestCases.size(); i++){
+            logi = logi.concat(((cmpTestCases.get(i).result_==true)?"SUCCESS":"FAILURE")+": Testing unknown command and wrong command length, command "+cmpTestCases.get(i).id()+"\n");
+            overallsuccess=(overallsuccess==true)?cmpTestCases.get(i).result_:overallsuccess;
+        }
+        
+        logi = logi.concat(((nostorecontainerres.result()==CommandResult.ROOTPA_ERROR_REGISTRY)?"SUCCESS":"FAILURE")+": executeCmpCommands (cat not  store container) returned: "+nostorecontainerres+"\n");
+        for(int i=0; i<cmpNoStoreContainerCases.size(); i++){
+            logi = logi.concat(((cmpNoStoreContainerCases.get(i).result_==true)?"SUCCESS":"FAILURE")+": Testing can not store container handling, command "+cmpNoStoreContainerCases.get(i).id()+"\n");
+            overallsuccess=(overallsuccess==true)?cmpNoStoreContainerCases.get(i).result_:overallsuccess;
+        }
+
+        logi = logi.concat(((nocontainerres.result()==CommandResult.ROOTPA_ERROR_REGISTRY_OBJECT_NOT_AVAILABLE)?"SUCCESS":"FAILURE")+": executeCmpCommands (no container) returned: "+nocontainerres+"\n");
+        for(int i=0; i<cmpNoContainerCases.size(); i++){
+            logi = logi.concat(((cmpNoContainerCases.get(i).result_==true)?"SUCCESS":"FAILURE")+": Testing no container handling, command "+cmpNoContainerCases.get(i).id()+"\n");
+            overallsuccess=(overallsuccess==true)?cmpNoContainerCases.get(i).result_:overallsuccess;
+        }
+
+        logi = logi.concat(((responseerrorres.result()==CommandResult.ROOTPA_ERROR_INTERNAL)?"SUCCESS":"FAILURE")+": executeCmpCommands (response errors) returned: "+responseerrorres+"\n");
+        for(int i=0; i<cmpResponseErrorCases.size(); i++){
+            logi = logi.concat(((cmpResponseErrorCases.get(i).result_==true)?"SUCCESS":"FAILURE")+": Testing response errors, command "+cmpResponseErrorCases.get(i).id()+"\n");
+            overallsuccess=(overallsuccess==true)?cmpResponseErrorCases.get(i).result_:overallsuccess;
+        }
+        
+        logi = logi.concat(((nullcres.result()==CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT)?"SUCCESS":"FAILURE")+": Testing executeCmpCommands with null command "+
+                ((nullcres.result()==CommandResult.ROOTPA_ERROR_ILLEGAL_ARGUMENT)?"\n":("returned "+nullcres+"\n")));
+        logi = logi.concat(((nullrres.result()==0x0FFFFFF0)?"SUCCESS":"FAILURE")+": Testing executeCmpCommands with null response "+
+                ((nullrres.result()==0x0FFFFFF0)?"\n":("returned "+nullrres+"\n")));
+        logi = logi.concat("==========================================================================\n");
+        stringList.add(logi);
+        return overallsuccess;
+    }
+    
+    void disconnect(){
+        provisioningServiceIfc_=null; 
+    }
+}
diff --git a/rootpa/Test/Common/mcStub/mcStub.c b/rootpa/Test/Common/mcStub/mcStub.c
index a69f1cd..bf35fb7 100755
--- a/rootpa/Test/Common/mcStub/mcStub.c
+++ b/rootpa/Test/Common/mcStub/mcStub.c
@@ -421,6 +421,8 @@
 
 #define ROOTID 7
 #define SPID 8
+#define SPID_UNKNOWN 12
+#define SPID_UNKNOWN_TLT_CONT_INDICES 16
 static const mcUuid_t TLTUUID={{3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6}};
 static const mcSoAuthTokenCont_t AUTHTOKENCONT={{16843009,16843009,(mcSoContext_t)16843009,(mcSoLifeTime_t)16843009,{16843009,
                                       {{2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}}},33686018,
@@ -468,6 +470,29 @@
                                   };
 
 
+static const mcSoSpCont_t SPCONT_UNKNOWN_TLT_CONT_INDICES={{16843009,16843009,(mcSoContext_t)16843009,(mcSoLifeTime_t)16843009,{16843009,                    // [header               
+                                  {{2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}}},33686018,                     // header                
+                                  50529027},{(contType_t)50529027,50529027,{(mcContainerState_t)4},50529027,                  // header] mcSpCont // state == 4 (SP_LOCKED)
+                                 {{{2,2,2,2,4,4,4,4,5,5,5,5,6,6,6,6}},{{2,2,2,2,                        // children 16/child 1
+                                  4,4,4,4,5,5,5,5,6,6,6,6}},{{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,                         // 2
+                                  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}},{{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,                         // 3
+                                  0xFF,0xFF,0xFF,0xFF}},{{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}},                        // 5
+                                  {{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}},{{0xFF,0xFF,0xFF,0xFF,                        // 6
+                                  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}},{{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,                         // 7
+                                  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}},{{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,                   // 8
+                                  0xFF,0xFF,0xFF,0xFF}},{{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}},                  // 10 childred so far
+                                  {{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}},{{0xFF,0xFF,0xFF,0xFF,                  // 11
+                                  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}},{{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,                   // 12 
+                                  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}},{{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,                   // 13
+                                  0xFF,0xFF,0xFF,0xFF}},{{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}},                  // 15 
+                                  {{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}},{{{0x10101010,      // mcSymmetricKey (8 ints)
+                                  0x11111111,0x11111111,0x11111111,0x11111111,0x11111111,                                              // 340
+                                  0x12121212,0x12121212}}}},{0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,                // 360
+                                  0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13, // 380
+                                  0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14}                     // 396
+                                  };
+                                  
+                                  
 static const mcSoTltCont_2_0_t TLTCONT={{16843009,16843009,(mcSoContext_t)16843009,(mcSoLifeTime_t)16843009,{16843009,                   // [header               
                                   {{2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}}},33686018,                        // header                
                                   50529027},{{(contType_t)0x03030303,0x03030303,{(mcContainerState_t)4},0x03030303,             // header]60  state=
@@ -488,6 +513,21 @@
 
 static const cmpMac_t MAC={{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32}};
 
+static const int CHANGING_AUTH_TOKEN_CONTAINER = 0xFE;
+    
+static const suidData_t ANOTHER_SUID = {{
+    0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0x01, 0x01, 0x01, 0x01
+}};
+
+static const suidData_t OFFSET_OUT_SUID={{
+    0x04, 0x05, 0x06, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0x01, 0x01, 0x01, 0x01 }};
+
+static const suidData_t OFFSET_PLUS_LEN_OUT_SUID={{
+    0x04, 0x05, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0x01, 0x01, 0x01, 0x01 }};
+
+static const suidData_t RESPONSE_ID_WRONG_SUID={{
+    0x04, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0x01, 0x01, 0x01, 0x01 }};
+   
 static const suidData_t SOFTWARE_SUID = {{
     0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
 }};
@@ -587,9 +627,13 @@
     if(memcmp(so,&AUTHTOKENCONT, smaller(size, sizeof(AUTHTOKENCONT)))==0)
     {
         return MC_DRV_OK;
-    }
+    }   
 
-    LOGE("FAILURE: mcStub:mcRegistryStoreAuthToken invalid authToken (size %d)", size);
+    if(so->soHeader.type != CHANGING_AUTH_TOKEN_CONTAINER) // checking special case for error case testing, that is not failure
+    {
+        LOGE("FAILURE: ");
+    }
+    LOGE("mcStub:mcRegistryStoreAuthToken invalid authToken (size %d)", size);    
     return MC_DRV_ERR_INVALID_PARAMETER;
 }
 
@@ -616,13 +660,28 @@
 mcResult_t mcRegistryReadSp(mcSpid_t spid, mcSoSpCont_t* container, uint32_t* size)
 {
     LOGI("mcStub:mcRegistryReadSp");
-    if(NULL==container || spid != SPID)
+
+    if(spid != SPID && spid != SPID_UNKNOWN_TLT_CONT_INDICES )
     {
-        LOGE("FAILURE: mcStub:mcRegistryReadSp invalid parameter container==%ld, spid==%d expecting %d", (long int) container,spid,SPID);
-        return MC_DRV_ERR_INVALID_PARAMETER;    
+        LOGE("mcStub:mcRegistryReadSp invalid parameter spid==%d expecting %d",spid,SPID); // in some tests this is expected
+        return MC_DRV_ERR_INVALID_DEVICE_FILE;
     }
+
+    if(NULL==container)
+    {
+        LOGE("FAILURE: mcStub:mcRegistryReadSp invalid parameter container==%ld", (long int) container);
+        return MC_DRV_ERR_INVALID_PARAMETER;
+    }
+    
     *size=sizeof(SPCONT);
-    memcpy(container, &SPCONT, *size); 
+    if(SPID_UNKNOWN_TLT_CONT_INDICES==spid)
+    {
+        memcpy(container, &SPCONT_UNKNOWN_TLT_CONT_INDICES, *size);     
+    }
+    else
+    {
+        memcpy(container, &SPCONT, *size); 
+    }
     return MC_DRV_OK;
 }
 
@@ -659,20 +718,28 @@
     return MC_DRV_OK;
 }
 
-mcResult_t mcRegistryReadTrustletCon(const mcUuid_t* uuid, mcSoTltCont_t* so, uint32_t* size)
+mcResult_t mcRegistryReadTrustletCon(const mcUuid_t* uuid, mcSpid_t spid, mcSoTltCont_t* so, uint32_t* size)
 {
     LOGI("mcStub:mcRegistryReadTrustletCon");
-    if(NULL==so || NULL==uuid || memcmp(&TLTUUID, uuid, sizeof(mcUuid_t))!=0)
+
+    if(NULL==so || NULL==uuid )
     {
-        LOGE("FAILURE: mcStub:mcRegistryReadTrustletCon invalid parameter %ld %ld", (long int) so, ((uuid==NULL)?(long int)uuid:(uint32_t)(uuid->value[0])));
+        LOGE("FAILURE: mcStub:mcRegistryReadTrustletCon invalid parameter %ld %ld", (long int) so, (long int)uuid);
         return MC_DRV_ERR_INVALID_PARAMETER;    
     }
+    
+    if(memcmp(&TLTUUID, uuid, sizeof(mcUuid_t))!=0)
+    {
+        LOGE("mcStub:mcRegistryReadSp invalid parameter uuid[0]==%d",(uint32_t)(uuid->value[0]));
+        return MC_DRV_ERR_INVALID_DEVICE_FILE;
+    }
+    
     *size=sizeof(TLTCONT);
     memcpy(so, &TLTCONT, *size); 
     return MC_DRV_OK;
 }
 
-mcResult_t mcRegistryStoreTrustletCon(const mcUuid_t *uuid, const mcSoTltCont_t *so, uint32_t size)
+mcResult_t mcRegistryStoreTrustletCon(const mcUuid_t *uuid, mcSpid_t spid, const mcSoTltCont_t *so, uint32_t size)
 {
     callRequiresTltWrite_=false;
     LOGI("mcStub:mcRegistryStoreTrustletCon");
@@ -693,12 +760,12 @@
     return MC_DRV_ERR_INVALID_PARAMETER;
 }
 
-mcResult_t mcRegistryCleanupTrustlet(const mcUuid_t* uuid)
+mcResult_t mcRegistryCleanupTrustlet(const mcUuid_t* uuid, mcSpid_t spid)
 {
     LOGI("mcStub:mcRegistryCleanupTrustlet");
     callRequiresTltCleanup_=false;
 
-    if(NULL==uuid || memcmp(&storedTltUuid_, uuid, sizeof(mcUuid_t))!=0 || memcmp(&TLTUUID, uuid, sizeof(mcUuid_t))!=0)
+    if(NULL==uuid || memcmp(&storedTltUuid_, uuid, sizeof(mcUuid_t))!=0 || memcmp(&TLTUUID, uuid, sizeof(mcUuid_t))!=0 )
     {
         LOGE("FAILURE: mcStub:mcRegistryCleanupTrustlet invalid parameter %ld %ld %d", (long int) uuid, ((uuid==NULL)?(long int)uuid:(uuid->value[0])), storedTltUuid_.value[0]);
         memset(&storedTltUuid_,0,sizeof(mcUuid_t));
@@ -708,29 +775,6 @@
     return MC_DRV_OK;
 }
 
-mcResult_t mcRegistryStoreData(const mcSoDataCont_t* so, uint32_t size)
-{
-    LOGI("mcStub:mcRegistryStoreData");
-    callRequiresDataWrite_=false;
-
-
-    if(NULL==so)
-    {
-        LOGE("FAILURE: mcStub:mcRegistryStoreData so == NULL");
-        return MC_DRV_ERR_INVALID_PARAMETER;    
-    }
-
-// comparing only first 140 bytes here because we never initialized more for testing
-    if(memcmp(so, &DATACONT, smaller(size, 140))==0)
-    {
-        return MC_DRV_OK;
-    }
-
-    LOGE("FAILURE: mcStub:mcRegistryStoreData not correctly formatted data cont %d ... %d", ((uint8_t*)so)[0],((uint8_t*)so)[139]);
-    return MC_DRV_ERR_INVALID_PARAMETER;
-
-}
-
 
 // internal functions for cmp message handling/checking ================================================================
 
@@ -805,6 +849,34 @@
     return (mappedMemory_+elementP->offset);
 }
 
+cmpMapOffsetInfo_t* accessElement(uint32_t elementNbr, uint8_t* wsmP)
+{
+    if(0==elementNbr) return NULL;
+    elementNbr--;    
+    cmpMapOffsetInfo_t* elementP=(cmpMapOffsetInfo_t*)(wsmP+sizeof(cmpResponseHeaderTci_t));
+    elementP+=elementNbr;
+    return elementP;
+}
+
+uint32_t getOffset(uint32_t elementNbr, uint8_t* wsmP)
+{
+    return accessElement(elementNbr, wsmP)->offset;
+}
+
+uint32_t getLen(uint32_t elementNbr, uint8_t* wsmP)
+{
+    return accessElement(elementNbr, wsmP)->len;
+}
+
+
+void modifyOffset(uint32_t elementNbr, uint8_t* wsmP, uint32_t offset, uint32_t len)
+{
+    LOGI("mcStub: modifyOffset %d %d %d", elementNbr, offset, len);    
+    accessElement(elementNbr, wsmP)->offset=offset;
+    accessElement(elementNbr, wsmP)->len=len;    
+}
+
+
 void handleGetSuid(uint8_t* cmpP, uint8_t* cmpRspP)
 {
     memcpy(((cmpRspGetSuid_t*)(cmpRspP))->suid.suidData.data, &SOFTWARE_SUID, sizeof(SOFTWARE_SUID));
@@ -833,19 +905,42 @@
 
 void handleGenerateAuthToken(uint8_t* cmpP, uint8_t* cmpRspP)
 {
-    if(!socAuthenticated_)
-    {
-        ((cmpResponseHeader_t*)(cmpRspP))->returnCode=RET_ERR_EXT_SECURITY_STATUS_NOT_SATISFIED;
-        return;
-    }
-   
+    suidData_t cmdSuid;
+    memcpy(&cmdSuid,&((cmpCmdGenAuthToken_t*)cmpP)->cmd.sdata.suid.suidData,sizeof(suidData_t));
     memcpy(&((cmpRspGenAuthToken_t*)(cmpRspP))->soAuthCont, &AUTHTOKENCONT ,sizeof(AUTHTOKENCONT));
+    uint8_t* containerTargetP=NULL;
+    containerTargetP=setElement(2, storedWsm_, sizeof(mcSoAuthTokenCont_t));        
+    memcpy(containerTargetP, &AUTHTOKENCONT ,sizeof(AUTHTOKENCONT));
+
+    /**
+    the following lines are for testing various error cases with RootPAClient
+    */    
+    if(memcmp(&ANOTHER_SUID,&cmdSuid,sizeof(suidData_t))==0)
+    {
+        ((mcSoAuthTokenCont_t*)containerTargetP)->soHeader.type=CHANGING_AUTH_TOKEN_CONTAINER;
+    }
+    else if(memcmp(&OFFSET_OUT_SUID,&cmdSuid,sizeof(suidData_t))==0)
+    {
+        // doing this with the container
+        uint32_t offset=getOffset(2,storedWsm_);
+        uint32_t len=getLen(2,storedWsm_);
+        offset=mappedMemoryLen_+3;
+        modifyOffset(2, storedWsm_, offset, len);
+    }
+    else if(memcmp(&OFFSET_PLUS_LEN_OUT_SUID,&cmdSuid,sizeof(suidData_t))==0)
+    {
+        // doing this with the actual message        
+        uint32_t offset=getOffset(1,storedWsm_);
+        uint32_t len=getLen(1,storedWsm_);
+        len=mappedMemoryLen_+3;
+        modifyOffset(1, storedWsm_, offset, len);
+    }
+    else if(memcmp(&RESPONSE_ID_WRONG_SUID,&cmdSuid,sizeof(suidData_t))==0)
+    {
+        *((uint32_t*)(cmpRspP))=RSP_ID(MC_CMP_CMD_BEGIN_SP_AUTHENTICATION); // could be anything but GEN_AUTH_TOKEN, we are using real value
+    }    
     
     ((cmpResponseHeader_t*)(cmpRspP))->returnCode=SUCCESSFUL; // (tlCmError.h)
-
-    uint8_t* containerTargetP=setElement(2, storedWsm_, sizeof(mcSoAuthTokenCont_t));
-
-    memcpy(containerTargetP, &AUTHTOKENCONT ,sizeof(AUTHTOKENCONT));
 }
 
 void handleAuthenticate(uint8_t* cmpP, uint8_t* cmpRspP)
@@ -1251,6 +1346,13 @@
 
 void handleAuthenticateTerminate(uint8_t* cmpP, uint8_t* cmpRspP)
 {
+    
+    if(!spAuthenticated_ && !socAuthenticated_ && !rootAuthenticated_)
+    {
+        ((cmpResponseHeader_t*)(cmpRspP))->returnCode=RET_ERR_EXT_SECURITY_STATUS_NOT_SATISFIED;
+        return;
+    }
+    
     socAuthenticated_=false;
     rootAuthenticated_=false;
     spAuthenticated_=false;
@@ -1487,7 +1589,7 @@
         LOGE("FAILURE: mcStub:handleMessage getting element failed %ld", (long int) origCmpP);
         return;
     }    
-    uint8_t* cmpP=malloc(cmpCommandLength+300);  // TODO-Tero: this +300 is here to get rid of Valgrind varnings. It seems that (at least) one of the messages
+    uint8_t* cmpP=malloc(cmpCommandLength+300);  // TODO-Tero: this +300 is here to get rid of Valgrind varnings. It seems that (at least) one of the messages   
     memset(cmpP, 0, cmpCommandLength+300);       // that has size of 116 when received from RootPA/Client is understood bigger in mcStub and it causes problems with Valgrind
     memcpy(cmpP, origCmpP, cmpCommandLength);    // very likely it is handleAuthenticate
     
@@ -1511,6 +1613,8 @@
     memset(cmpRspP, 0, mcStub_getResponseSize(commandId));
     cmpResponseHeaderTci_t* responseInfoP = (cmpResponseHeaderTci_t*) storedWsm_;    
 
+    *((uint32_t*)(mappedMemory_))=RSP_ID(commandId);
+    
     if(sessionOpen_==false)
     {
         LOGI("mcStub.handleMessage: FAILURE, session not open");
@@ -1609,11 +1713,17 @@
     free(cnt1P);
     free(cnt2P);
 
-    *((uint32_t*)(mappedMemory_))=RSP_ID(commandId);
     responseInfoP->version=NEW_CMP_VERSION;
-    responseInfoP->responseId=RSP_ID(commandId);        
+    responseInfoP->responseId=*((uint32_t*)(mappedMemory_));
     responseInfoP->len=0;
-    LOGI("mcStub: returning wsmP_ ver=0x%x rspId=0x%x neededBytes=%d elementoff=%d, elementSize=%d", *((int*)storedWsm_), *((int*)(storedWsm_+4)), *((int*)(storedWsm_+8)), *((int*)(storedWsm_+12)), *((int*)(storedWsm_+16)) );
+    LOGI("mcStub: returning wsmP_ ver=0x%x rspId=0x%x neededBytes=%d elementoff=%d, elementSize=%d container1off=%d, container1Size=%d", 
+                                                        *((int*)storedWsm_), 
+                                                        *((int*)(storedWsm_+4)), 
+                                                        *((int*)(storedWsm_+8)), 
+                                                        *((int*)(storedWsm_+12)), 
+                                                        *((int*)(storedWsm_+16)), 
+                                                        *((int*)(storedWsm_+20)), 
+                                                        *((int*)(storedWsm_+24)));
 
     return;
 }
diff --git a/rootpa/Test/Linux/commonClient/Makefile b/rootpa/Test/Linux/commonClient/Makefile
index da2f35a..23679e5 100755
--- a/rootpa/Test/Linux/commonClient/Makefile
+++ b/rootpa/Test/Linux/commonClient/Makefile
@@ -31,10 +31,10 @@
 
 
 # sudo apt-get install libxml2-devel
-# sudo apt-get install libcurl4-openssl-dev
-
-MOBICORE=/home/tersou01/mc/Common/MobiCore/trunk/00027125
-MOBICOREDRIVERLIB=/home/tersou01/mc/Common/MobiCoreDriverLib/trunk/00027038
+# sudo apt-get install libcurl4-openssl-d
+TLCM=/home/tersou01/mc/Common/TlCm/trunk/00028991
+TLSDK=/home/tersou01/mc/Common/TlSdk/trunk/00028826
+MOBICOREDRIVERLIB=/home/tersou01/mc/Common/MobiCoreDriverLib/trunk/00028995
 
 LIBXML2 = /usr/lib/x86_64-linux-gnu/libxml2.a
 LIBCURL = /usr/lib/x86_64-linux-gnu/libcurl.a
@@ -56,7 +56,7 @@
 CFLAGS= -Wall -D_GNU_SOURCE   # -D_GNU_SOURCE is here for removing warnings and making sure strcasestr works properly
 
 LDFLAGS=rcs
-INCDIR=-I../../../Code/Common/include -I/usr/include/libxml2 -I/usr/include/curl -I$(MOBICORE)/Out/inc -I$(MOBICOREDRIVERLIB)/Out/Public
+INCDIR=-I../../../Code/Common/include -I/usr/include/libxml2 -I/usr/include/curl -I$(TLSDK)/Out/Public/MobiCore/inc -I$(TLCM)/Out/Public -I$(MOBICOREDRIVERLIB)/Out/Public
 _SOURCEDIR=../../../Code/Common
 SOURCES=$(_SOURCEDIR)/*.c
 OBJECTS=*.o
@@ -89,6 +89,6 @@
 
 clean:
 	rm -rf *.o
-	rm -rf *.xsdrm     
+	rm -rf *.xsd
 	rm -rf $(ROOTPALIB)
 	rm -rf $(TESTAPP)     
diff --git a/rootpa/Test/Linux/commonClient/cmpHandler.cpp b/rootpa/Test/Linux/commonClient/cmpHandler.cpp
index 76be45d..cbf4e85 100755
--- a/rootpa/Test/Linux/commonClient/cmpHandler.cpp
+++ b/rootpa/Test/Linux/commonClient/cmpHandler.cpp
@@ -412,7 +412,18 @@
     bool result=true;
     for(int i=0;i<numberOfCommands;i++)
     {
-        if(responsesP[i].length <= 0 || *((uint32_t*)responsesP[i].contentP+RETCODE_INDEX) != 0)
+        uint32_t retCode=0;
+        
+        if(0==i || 1==i || 4==i)
+        {
+            *((uint32_t*)responsesP[i].contentP+OLD_RETCODE_INDEX);
+        }
+        else
+        {
+            *((uint32_t*)responsesP[i].contentP+RETCODE_INDEX);        
+        }
+        
+        if(responsesP[i].length <= 0 || retCode != 0)
         {
             cout << "==== FAILURE: cmpResult "<< i << "\n";
             result=false;
diff --git a/rootpa/Test/Linux/commonClient/cmpHandler.h b/rootpa/Test/Linux/commonClient/cmpHandler.h
index 8cea4f9..528f381 100755
--- a/rootpa/Test/Linux/commonClient/cmpHandler.h
+++ b/rootpa/Test/Linux/commonClient/cmpHandler.h
@@ -31,6 +31,7 @@
 #include <rootpa.h>
 
 #define RETCODE_INDEX 3
+#define OLD_RETCODE_INDEX 1
 
 int createCommands(CmpMessage** commandsP, CmpMessage** responsesP);
 bool checkCmpResults(int numberOfCommands, CmpMessage* responsesP);
diff --git a/rootpa/Test/Linux/commonClient/rootpaclient.cpp b/rootpa/Test/Linux/commonClient/rootpaclient.cpp
index 04f61fc..b9ee744 100755
--- a/rootpa/Test/Linux/commonClient/rootpaclient.cpp
+++ b/rootpa/Test/Linux/commonClient/rootpaclient.cpp
@@ -185,7 +185,7 @@
 int main(int argc, char* argv[] )

 {   

 //    printSizes();

-    setPaths("./");

+    setPaths("./", "./");

     checkResult(setSeAddress(SEADDRESS, sizeof(SEADDRESS)),"setSeAddress");

     

     checkResult(openSessionToCmtl(), "openSessionToCmtl");

@@ -284,7 +284,7 @@
     if(checkResult( executeCmpCommands(numberOfCommands, commandsP, responsesP, &internalError),"executeCmpCommands" ))

     {

         checkResult( 0==internalError,"executeCmpCommands, internalError");

-        checkCmpResults(numberOfCommands, responsesP);

+        testStatus_=checkCmpResults(numberOfCommands, responsesP);

     }

     cleanup(numberOfCommands, commandsP, responsesP);

     

diff --git a/rootpa/Test/Misc/cgi-bin/delete b/rootpa/Test/Misc/cgi-bin/delete
index 76a8199..254e249 100755
--- a/rootpa/Test/Misc/cgi-bin/delete
+++ b/rootpa/Test/Misc/cgi-bin/delete
@@ -67,9 +67,8 @@
 
 
     } else {
-        $r->log->notice("RootPATest.delete: HTTP command was not DELETE, returning cmp command for root cont delete");
+        $r->log->notice("RootPATest.delete: HTTP command was not DELETE, but $r->method() returning cmp command for root cont delete");
     }
-    
 
     return Apache2::Const::OK;
 } 
diff --git a/rootpa/Test/Misc/cgi-bin/empty b/rootpa/Test/Misc/cgi-bin/empty
index abce4bd..7d52735 100755
--- a/rootpa/Test/Misc/cgi-bin/empty
+++ b/rootpa/Test/Misc/cgi-bin/empty
@@ -49,8 +49,11 @@
         } else {
             $r->log->notice("RootPATest.empty: HTTP command was not POST or PUT");
 	        if ( $r->method() eq "DELETE") { 
-			$r->log->notice("RootPATest.empty: but DELETE, how did we get here?");
-		}
+                $r->log->notice("RootPATest.empty: but DELETE, how did we get here?");
+            }else{
+                $r->log->notice("RootPATest.empty: but $r->method()");             
+            }
+            
         }
     }
     
diff --git a/rootpa/Test/Misc/cgi-bin/errorcases b/rootpa/Test/Misc/cgi-bin/errorcases
new file mode 100755
index 0000000..cb3ebff
--- /dev/null
+++ b/rootpa/Test/Misc/cgi-bin/errorcases
@@ -0,0 +1,164 @@
+#!/usr/bin/perl
+
+
+#
+# for this to work, perl module needs to be installed.
+# in ubuntu run
+#
+# sudo apt-get install libapache2-mod-perl2
+# sudo apache2ctl restart 
+# sudo  a2enmod perl
+# These scripts print to  /var/log/apache2/error.log
+
+package ReceiveCommandExpectingErrors;
+use strict;
+
+use Apache2::RequestIO (); 
+use Apache2::RequestUtil (); 
+use Apache2::RequestRec (); 
+use Apache2::Log (); 
+
+use Apache2::Const -compile => qw(OK DECLINED :log); 
+
+#
+# 10 unknown id
+# 11 too long message
+# BEGIN_ROOT_AUTHENTICATION(1): AQAAAJQBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO3eAAA=
+# 12 too short message
+# AUTHENTICATE(0): AAAAAA==
+# 13-14  preparation
+# BEGIN_SP_AUTHENTICATION(3): AwAAABAAAAAAAAAACAAAAA==
+# AUTHENTICATE(0): AAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyA=
+# 15 no SP container
+# TLT_CONT_LOCK_BY_SP(21): FQAAAEAAAAAAAAAACAAAAAEBAQEJCQkJAQEBAQkJCQkBAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fIA==
+# 16 terminate
+# AUTHENTICATE_TERMINATE(28): HAAAACwAAAAAAAAAAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyA=
+# 17 can not store
+# GENERATE_AUTH_TOKEN(4): BAAAAAAAAABEVWZ3iJmquwEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+# 18 response id wrong
+# GENERATE_AUTH_TOKEN(4): BAAAAAAAAAAEVWZ3iJmquwEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+# 19 offset plus length out
+# GENERATE_AUTH_TOKEN(4): BAAAAAAAAAAEBWZ3iJmquwEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+# 10 offset out
+# GENERATE_AUTH_TOKEN(4): BAAAAAAAAAAEBQZ3iJmquwEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+#
+# 21 unparseable base64, ignore error = false
+# 22 unparseable base64
+#
+# ====================== expected result ====================== 
+#
+# <commandResultList>
+#      <commandResult id="10">
+#         <resultError errorCode="COMMAND_NOT_SUPPORTED_ERROR"/>
+#     </commandResult>
+#     <commandResult id="11">
+#         <resultValue>AQAAgAAAAAAAAAAAAAAAAAAAAABEVWZ3iJmqu8zd7v8DAwMDAwMDAwkJCQkJCQkJCgoKCgoKCgoKCgoKCgoKCgoKCgoLCwsL</resultValue>
+#     </commandResult>
+#     <commandResult id="12">
+#         <resultValue>AAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</resultValue>
+#     </commandResult>
+#     <commandResult id="13">
+#         <resultValue>AwAAgAAAAAAAAAAAAAAAAAAAAABEVWZ3iJmqu8zd7v8IAAAAAwMDAwMDAwMSEhISEhISEhISEhITExMTExMTExMTExMTExMTExMTEw==</resultValue>
+#     </commandResult>
+#     <commandResult id="14">
+#         <resultValue>AAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8g</resultValue>
+#     </commandResult>
+#     <commandResult id="15">
+#         <resultError errorCode="REGISTRY_OBJECT_NOT_AVAILABLE" errorDetail="16"/>
+#     </commandResult>
+#     <commandResult id="16">
+#         <resultValue>HAAAgAAAAAAAAAAAAAAAAAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8g</resultValue>
+#     </commandResult>
+#     <commandResult id="17">
+#         <resultError errorCode="REGISTRY_ERROR" errorDetail="17"/>
+#     </commandResult>
+#     <commandResult id="18">
+#         <resultError errorCode="INTERNAL_ERROR"/>  #### or COMMAND_EXECUTION_ERROR if it gets included
+#     </commandResult>
+#     <commandResult id="19">
+#         <resultError errorCode="INTERNAL_ERROR"/>
+#     </commandResult>
+#     <commandResult id="20">
+#         <resultError errorCode="INTERNAL_ERROR" errorDetail="-1"/>
+#     </commandResult>
+#     <commandResult id="21">
+#         <resultError errorCode="COMMAND_NOT_SUPPORTED_ERROR"/>
+#     </commandResult>
+# </commandResultList>
+# </ContentManagementResponse>\n'
+#
+
+sub handler { 
+    my $r = shift; 
+
+    # handle POST requests 
+    if ( $r->method() eq "POST" ) { 
+
+        # create a post data buffer 
+        my $PostBuffer = ''; 
+
+        # loop over each line of data 
+        $r->log->notice("RootPATest.errorcases: Post Command Received. Data:"); 
+        while($r->read($PostBuffer, 1024)) { 
+            $r->log->notice("'$PostBuffer'"); 
+        } 
+
+	    $r->content_type('text/plain');
+	    
+	    print "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?> 
+	    <ContentManagementRequest xmlns=\"http://www.mcore.gi-de.com/2012/04/schema/EnrollmentService\">
+		<commands>
+		    <command id=\"10\" type=\"CMP\" ignoreError=\"true\">
+		        <commandValue>zzzzzz==</commandValue>
+		    </command>
+            <command id=\"11\" type=\"CMP\" ignoreError=\"true\">
+		        <commandValue>AQAAAJQBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO3eAAA=</commandValue>
+		    </command>
+		    <command id=\"12\" type=\"CMP\" ignoreError=\"true\">
+		        <commandValue>AAAAAA==</commandValue>
+		    </command>
+		    <command id=\"13\" type=\"CMP\" ignoreError=\"true\">
+		        <commandValue>AwAAABAAAAAAAAAACAAAAA==</commandValue>
+		    </command>
+		    <command id=\"14\" type=\"CMP\" ignoreError=\"true\">
+		        <commandValue>AAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyA=</commandValue>
+		    </command>
+		    <command id=\"15\" type=\"CMP\" ignoreError=\"true\">
+		        <commandValue>FQAAAEAAAAAAAAAACAAAAAEBAQEJCQkJAQEBAQkJCQkBAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fIA==</commandValue>
+		    </command>
+		    <command id=\"16\" type=\"CMP\" ignoreError=\"true\">
+		        <commandValue>HAAAACwAAAAAAAAAAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyA=</commandValue>
+		    </command>
+		    <command id=\"17\" type=\"CMP\" ignoreError=\"true\">
+		        <commandValue>BAAAAAAAAABEVWZ3iJmquwEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</commandValue>
+		    </command>
+		    <command id=\"18\" type=\"CMP\" ignoreError=\"true\">
+		        <commandValue>BAAAAAAAAAAEVWZ3iJmquwEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</commandValue>
+		    </command>
+		    <command id=\"19\" type=\"CMP\" ignoreError=\"true\">
+		        <commandValue>BAAAAAAAAAAEBWZ3iJmquwEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</commandValue>
+		    </command>
+		    <command id=\"20\" type=\"CMP\" ignoreError=\"true\">
+		        <commandValue>BAAAAAAAAAAEBQZ3iJmquwEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</commandValue>
+		    </command>
+		    <command id=\"21\" type=\"CMP\" ignoreError=\"false\">
+		        <commandValue>dasd5fg54bvfgty56000cs?4fds45ggytr??=DFGGDFGSDGGDSGS</commandValue>
+		    </command>
+		    <command id=\"22\" type=\"CMP\" ignoreError=\"true\">
+		        <commandValue>dasd5fg54bvfgty56000cs?4fds45ggytr??=DFGGDFGSDGGDSGS</commandValue>
+		    </command>
+        </commands>
+	    </ContentManagementRequest>";
+    }  else {
+        $r->log->notice("RootPATest.errorcases: HTTP command was not POST");
+            $r->log->notice("RootPATest.errorcases: but $r->method()"); 
+    }
+    
+    return Apache2::Const::OK;
+} 
+
+1;
+
+
+
+
diff --git a/rootpa/Test/Misc/cgi-bin/first b/rootpa/Test/Misc/cgi-bin/first
index 9952f43..c670861 100755
--- a/rootpa/Test/Misc/cgi-bin/first
+++ b/rootpa/Test/Misc/cgi-bin/first
@@ -1,18 +1,13 @@
 #!/usr/bin/perl
 
-
 #
 # for this to work, perl module needs to be installed.
 # in ubuntu run
 #
 # sudo apt-get install libapache2-mod-perl2
 # sudo apache2ctl restart
-#   
-# These scripts print to  /var/log/apache2/error.log
 # sudo  a2enmod perl
-#
-# "sudo a2enmod dav" to enable support for DELETE
-
+# These scripts print to  /var/log/apache2/error.log
 
 package ReceiveFirstCommand;
 use strict;
@@ -63,6 +58,10 @@
 		</commands>
 	    </ContentManagementRequest>";
 
+    
+    }  else {
+        $r->log->notice("RootPATest.first: HTTP command was not POST");
+            $r->log->notice("RootPATest.first: but $r->method()"); 
     }
     
     return Apache2::Const::OK;
diff --git a/rootpa/Test/Misc/cgi-bin/second b/rootpa/Test/Misc/cgi-bin/second
index e6d9e47..2806da8 100755
--- a/rootpa/Test/Misc/cgi-bin/second
+++ b/rootpa/Test/Misc/cgi-bin/second
@@ -67,9 +67,9 @@
         $r->log->notice("RootPATest.second: HTTP command was not POST");
         if( $r->method() eq "DELETE" ) { 
         # handle DELETE requests     
-                $r->log->notice("RootPATest.second: but DELETE"); 
+            $r->log->notice("RootPATest.second: but DELETE"); 
         } else {
-
+            $r->log->notice("RootPATest.second: but $r->method()"); 
         }
     }
     
diff --git a/rootpa/Test/Misc/configureApache.sh b/rootpa/Test/Misc/configureApache.sh
index 7661bca..f5cd4e2 100755
--- a/rootpa/Test/Misc/configureApache.sh
+++ b/rootpa/Test/Misc/configureApache.sh
@@ -1,12 +1,11 @@
 #!/bin/bash
-
-echo "This script has to be run in Misc folder with root permissions"
+echo "This script has to be run with root permissions"
+cd $(dirname $0)
 
 cp -rf cgi-bin /var/www
 cp -f index.html /var/www
-cp -f httpd.conf /etc/apache2/
 
-if [ -d /etc/apache2/conf.d ]
+if [[ -d /etc/apache2/conf.d ]]
 then
     cp -f httpd.conf /etc/apache2/conf.d/httpd.local.conf
 else
diff --git a/rootpa/Test/Misc/httpd.conf b/rootpa/Test/Misc/httpd.conf
index f1af4e2..64a2f08 100755
--- a/rootpa/Test/Misc/httpd.conf
+++ b/rootpa/Test/Misc/httpd.conf
@@ -22,21 +22,22 @@
 PerlRequire /var/www/cgi-bin/testi
 PerlRequire /var/www/cgi-bin/empty
 PerlRequire /var/www/cgi-bin/delete
+PerlRequire /var/www/cgi-bin/errorcases
+
+#
+# Note! It seems that the order of the entries matters here. The shorter "Location" has to be before the longer, but similar ones, if not
+# the shorter "Location will be used". That is why DELETE is before the ones with SPID. The actual value of SPID does not matter.
+#
+#
+
 
 # intial DELETE uses this
 <Location /00000000445566778899aabbccddeeff>
-    Header set Link <http://10.0.2.2/activity/00000000-4455-6677-8899-aabbccddeef2>;rel="http://10.0.2.2/relation/command_result"
+    Header set Link <http://10.0.2.2/activity/00000000-4455-6677-8899-aabbccddee00>;rel="http://10.0.2.2/relation/command_result"
     SetHandler perl-script
     PerlResponseHandler ReceiveDeleteCommand
 </Location>
 
-# intial POST uses this
-<Location /00000000445566778899aabbccddeeff/8>
-    Header set Link <http://10.0.2.2/activity/00000000-4455-6677-8899-aabbccddeef2>;rel="http://10.0.2.2/relation/command_result"
-    SetHandler perl-script
-    PerlResponseHandler ReceiveFirstCommand
-</Location>
-
 # intial POST/Install uses this
 <Location /00000000445566778899aabbccddeeff/0>
     Header set Link <http://10.0.2.2/activity/00000000-4455-6677-8899-aabbccddeef2>;rel="http://10.0.2.2/relation/command_result"
@@ -44,8 +45,22 @@
     PerlResponseHandler ReceiveFirstCommand
 </Location>
 
+# intial POST uses this
+<Location /00000000445566778899aabbccddeeff/8>
+    Header set Link <http://10.0.2.2/activity/00000000-4455-6677-8899-aabbccddeef2>;rel="http://10.0.2.2/relation/command_result"
+    SetHandler perl-script
+    PerlResponseHandler ReceiveFirstCommand
+</Location>
+
+# intial POST for error cases uses this
+<Location /00000000445566778899aabbccddeeff/12>
+    Header set Link <http://10.0.2.2/activity/00000000-4455-6677-8899-aabbccddee00>;rel="http://10.0.2.2/relation/command_result"
+    SetHandler perl-script
+    PerlResponseHandler ReceiveCommandExpectingErrors
+</Location>
+
 <Location /testi>
-    SetHandler perl-scriptq
+    SetHandler perl-script
     PerlResponseHandler Hello
 </Location>
 
diff --git a/rootpa/Test/Misc/squid.conf b/rootpa/Test/Misc/squid.conf
new file mode 100755
index 0000000..f5c6285
--- /dev/null
+++ b/rootpa/Test/Misc/squid.conf
@@ -0,0 +1,31 @@
+#	WELCOME TO SQUID 3.1.20
+#	----------------------------
+
+
+#
+# Recommended minimum configuration:
+#
+acl manager proto cache_object
+acl localhost src 127.0.0.1/32 ::1
+acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1
+
+
+acl SSL_ports port 443
+acl Safe_ports port 80		# http
+acl Safe_ports port 443		# https
+
+acl CONNECT method CONNECT
+
+http_access allow localhost
+http_access allow all
+
+http_port 8080
+
+coredump_dir /var/spool/squid3
+
+# Add any of your own refresh_pattern entries above these.
+refresh_pattern -i (/cgi-bin/|\?) 0	0%	0
+refresh_pattern .		0	20%	4320
+
+ignore_expect_100 off
+