+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putBoolean(PassCodeActivity.KEY_CONFIRMING_PASSCODE, mConfirmingPassCode);
+        outState.putStringArray(PassCodeActivity.KEY_PASSCODE_DIGITS, mPassCodeDigits);
+    }
+
+
+    private class PassCodeDigitTextWatcher implements TextWatcher {
+
+        private int mIndex = -1;
+        private boolean mLastOne = false;
+
+        /**
+         * Constructor
+         *
+         * @param index         Position in the pass code of the input field that will be bound to
+         *                      this watcher.
+         * @param lastOne       'True' means that watcher corresponds to the last position of the
+         *                      pass code.
+         */
+        public PassCodeDigitTextWatcher(int index, boolean lastOne) {
+            mIndex = index;
+            mLastOne  = lastOne;
+            if (mIndex < 0) {
+                throw new IllegalArgumentException(
+                        "Invalid index in " + PassCodeDigitTextWatcher.class.getSimpleName() +
+                                " constructor"
+                );
+            }
+        }
+
+        private int next() {
+            return mLastOne ? 0 : mIndex + 1;
+        }
+
+        /**
+         * Performs several actions when the user types a digit in an input field:
+         *  - saves the input digit to the state of the activity; this will allow retyping the
+         *    pass code to confirm it.
+         *  - moves the focus automatically to the next field
+         *  - for the last field, triggers the processing of the full pass code
+         *
+         * @param s
+         */
+        @Override
+        public void afterTextChanged(Editable s) {
+            if (s.length() > 0) {
+                if (!mConfirmingPassCode) {
+                    mPassCodeDigits[mIndex] = mPassCodeEditTexts[mIndex].getText().toString();
+                }
+                mPassCodeEditTexts[next()].requestFocus();
+
+                if (mLastOne) {
+                    processFullPassCode();
+                }
+
+            } else {
+                Log_OC.d(TAG, "Text box " + mIndex + " was cleaned");
+            }
+        }
+
+        @Override
+        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+            // nothing to do
+        }
+
+        @Override
+        public void onTextChanged(CharSequence s, int start, int before, int count) {
+            // nothing to do
+        }
+
+    }
+
+