text:
/**
 * User ID token unit tests.
 *
 * @author Wesley Miaw <wmiaw@netflix.com>
 */
describe("UserIdToken", function() {
    /** Milliseconds per second. */
    var MILLISECONDS_PER_SECOND = 1000;

    /** JSON key token data. */
    var KEY_TOKENDATA = "tokendata";
    /** JSON key signature. */
    var KEY_SIGNATURE = "signature";

    // tokendata
    /** JSON key renewal window timestamp. */
    var KEY_RENEWAL_WINDOW = "renewalwindow";
    /** JSON key expiration timestamp. */
    var KEY_EXPIRATION = "expiration";
    /** JSON key master token serial number. */
    var KEY_MASTER_TOKEN_SERIAL_NUMBER = "mtserialnumber";
    /** JSON key user ID token serial number. */
    var KEY_SERIAL_NUMBER = "serialnumber";
    /** JSON key token user identification data. */
    var KEY_USERDATA = "userdata";

    // userdata
    /** JSON key issuer data. */
    var KEY_ISSUER_DATA = "issuerdata";
    /** JSON key identity. */
    var KEY_IDENTITY = "identity";

    /** MSL context. */
    var ctx;

    var RENEWAL_WINDOW = new Date(Date.now() + 120000);
    var EXPIRATION = new Date(Date.now() + 180000);
    var MASTER_TOKEN;
    var SERIAL_NUMBER = 42;
    var ISSUER_DATA = { issuerid: 17 };
    var USER = MockEmailPasswordAuthenticationFactory.USER;

    var initialized = false;
    beforeEach(function() {
    	if (!initialized) {
            runs(function() {
                MockMslContext$create(EntityAuthenticationScheme.PSK, false, {
                    result: function(c) { ctx = c; },
                    error: function(e) { expect(function() { throw e; }).not.toThrow(); }
                });
            });
            waitsFor(function() { return ctx; }, "ctx", 100);
    		runs(function() {
    			MslTestUtils.getMasterToken(ctx, 1, 1, {
    				result: function(token) { MASTER_TOKEN = token; },
    				error: function(e) { expect(function() { throw e; }).not.toThrow(); },
    			});
    		});
    		waitsFor(function() { return MASTER_TOKEN; }, "master token not received", 100);
    		runs(function() { initialized = true; });
    	}
    });

    it("ctors", function() {
        var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var jsonString;
        runs(function() {
	        expect(userIdToken.isDecrypted()).toBeTruthy();
	        expect(userIdToken.isVerified()).toBeTruthy();
	        expect(userIdToken.isRenewable(null)).toBeFalsy();
	        expect(userIdToken.isExpired(null)).toBeFalsy();
	        expect(userIdToken.isBoundTo(MASTER_TOKEN)).toBeTruthy();
	        expect(userIdToken.issuerData).toEqual(ISSUER_DATA);
	        expect(userIdToken.user).toEqual(USER);
	        expect(userIdToken.expiration.getTime() / MILLISECONDS_PER_SECOND).toEqual(Math.floor(EXPIRATION.getTime() / MILLISECONDS_PER_SECOND));
	        expect(userIdToken.mtSerialNumber).toEqual(MASTER_TOKEN.serialNumber);
	        expect(userIdToken.renewalWindow.getTime() / MILLISECONDS_PER_SECOND).toEqual(Math.floor(RENEWAL_WINDOW.getTime() / MILLISECONDS_PER_SECOND));
	        expect(userIdToken.serialNumber).toEqual(SERIAL_NUMBER);
	        jsonString = JSON.stringify(userIdToken);
	        expect(jsonString).not.toBeNull();
        });

        var joUserIdToken;
        runs(function() {
            var jo = JSON.parse(jsonString);
            UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
                result: function(token) { joUserIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return joUserIdToken; }, "joUserIdToken not received", 100);

        runs(function() {
	        expect(joUserIdToken.isDecrypted()).toEqual(userIdToken.isDecrypted());
	        expect(joUserIdToken.isVerified()).toEqual(userIdToken.isVerified());
	        expect(joUserIdToken.isRenewable(null)).toEqual(userIdToken.isRenewable(null));
	        expect(joUserIdToken.isExpired(null)).toEqual(userIdToken.isExpired(null));
	        expect(joUserIdToken.isBoundTo(MASTER_TOKEN)).toBeTruthy();
	        expect(joUserIdToken.issuerData).toEqual(userIdToken.issuerData);
	        expect(joUserIdToken.user).toEqual(userIdToken.user);
	        expect(joUserIdToken.expiration.getTime() / MILLISECONDS_PER_SECOND).toEqual(userIdToken.expiration.getTime() / MILLISECONDS_PER_SECOND);
	        expect(joUserIdToken.mtSerialNumber).toEqual(userIdToken.mtSerialNumber);
	        expect(joUserIdToken.renewalWindow.getTime() / MILLISECONDS_PER_SECOND).toEqual(userIdToken.renewalWindow.getTime() / MILLISECONDS_PER_SECOND);
	        expect(joUserIdToken.serialNumber).toEqual(userIdToken.serialNumber);
	        var joJsonString = JSON.stringify(joUserIdToken);
	        expect(joJsonString).not.toBeNull();
	        expect(joJsonString).toEqual(jsonString);
        });
    });

    it("negative serial number ctor", function() {
    	var serialNumber = -1;

    	var exception;
    	runs(function() {
    		UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, serialNumber, ISSUER_DATA, USER, {
    		    result: function() {},
    		    error: function(err) { exception = err; },
    		});
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
    	runs(function() {
    	    var f = function() { throw exception; };
    	    expect(f).toThrow(new MslInternalException());
    	});
    });

    it("too large serial number ctor", function() {
    	var serialNumber = MslConstants$MAX_LONG_VALUE + 2;

    	var exception;
    	runs(function() {
    		UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, serialNumber, ISSUER_DATA, USER, {
    			result: function() {},
    			error: function(err) { exception = err; },
    		});
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
    	runs(function() {
    		var f = function() { throw exception; };
    		expect(f).toThrow(new MslInternalException());
    	});
    });

    it("null master token", function() {
    	var exception;
    	runs(function() {
    		UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, null, SERIAL_NUMBER, ISSUER_DATA, USER, {
    		    result: function() {},
    		    error: function(err) { exception = err; },
    		});
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
    	runs(function() {
    	    var f = function() { throw exception; };
    	    expect(f).toThrow(new MslInternalException());
    	});
    });

    it("master token mismtached", function() {
    	var masterToken = undefined, joMasterToken;
    	runs(function() {
    		MslTestUtils.getMasterToken(ctx, 1, 1, {
    			result: function(token) { masterToken = token; },
    			error: function(e) { expect(function() { throw e; }).not.toThrow(); }
    		});
    		MslTestUtils.getMasterToken(ctx, 1, 2, {
    			result: function(token) { joMasterToken = token; },
    			error: function(e) { expect(function() { throw e; }).not.toThrow(); }
    		});
    	});
    	waitsFor(function() { return masterToken && joMasterToken; }, "master token not received", 100);

    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, masterToken, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        UserIdToken$parse(ctx, JSON.parse(JSON.stringify(userIdToken)), joMasterToken, {
	            result: function() {},
	            error: function(err) { exception = err; },
	        });
		});
		waitsFor(function() { return exception; }, "exception not received", 100);
    	runs(function() {
    	    var f = function() { throw exception; };
    	    expect(f).toThrow(new MslException(MslError.USERIDTOKEN_MASTERTOKEN_MISMATCH));
    	});
    });

    it("master token null", function() {
    	var masterToken;
    	runs(function() {
    		MslTestUtils.getMasterToken(ctx, 1, 1, {
    			result: function(token) { masterToken = token; },
    			error: function(e) { expect(function() { throw e; }).not.toThrow(); }
    		});
    	});
    	waitsFor(function() { return masterToken; }, "master token not received", 100);

    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, masterToken, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        UserIdToken$parse(ctx, JSON.parse(JSON.stringify(userIdToken)), null, {
	            result: function() {},
	            error: function(err) { exception = err; },
	        });
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
    	runs(function() {
    	    var f = function() { throw exception; };
    	    expect(f).toThrow(new MslException(MslError.USERIDTOKEN_MASTERTOKEN_MISMATCH));
    	});
    });

    it("inconsistent expiration", function() {
    	var expiration = new Date(Date.now() - 1);
    	var renewalWindow = new Date();
    	expect(expiration.getTime()).toBeLessThan(renewalWindow.getTime());

    	var exception;
    	runs(function() {
	        UserIdToken$create(ctx, renewalWindow, expiration, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
	            result: function() {},
	            error: function(err) { exception = err; },
	        });
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
    	runs(function() {
    	    var f = function() { throw exception; };
    	    expect(f).toThrow(new MslInternalException());
    	});
    });

    it("inconsistent expiration json", function() {
    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        var jsonString = JSON.stringify(userIdToken);
	        var jo = JSON.parse(jsonString);

	        var tokendata = base64$decode(jo[KEY_TOKENDATA]);
	        var tokendataJo = JSON.parse(textEncoding$getString(tokendata, MslConstants$DEFAULT_CHARSET));
	        tokendataJo[KEY_EXPIRATION] = (Date.now() / MILLISECONDS_PER_SECOND) - 1;
	        tokendataJo[KEY_RENEWAL_WINDOW] = Date.now() / MILLISECONDS_PER_SECOND;
	        jo[KEY_TOKENDATA] = base64$encode(textEncoding$getBytes(JSON.stringify(tokendataJo), MslConstants$DEFAULT_CHARSET));

	        UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
	            result: function() {},
	            error: function(err) { exception = err; },
	        });
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
    	runs(function() {
    	    var f = function() { throw exception; };
    	    expect(f).toThrow(new MslException(MslError.USERIDTOKEN_EXPIRES_BEFORE_RENEWAL));
    	});
    });

    it("missing tokendata", function() {
    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        var jsonString = JSON.stringify(userIdToken);
	        var jo = JSON.parse(jsonString);

	        expect(jo[KEY_TOKENDATA]).not.toBeNull();
	        delete jo[KEY_TOKENDATA];

	        UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
	            result: function() {},
	            error: function(err) { exception = err; },
	        });
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
    	runs(function() {
    	    var f = function() { throw exception; };
    	    expect(f).toThrow(new MslEncodingException(MslError.JSON_PARSE_ERROR));
    	});
    });

    it("invalid tokendata", function() {
    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        var jsonString = JSON.stringify(userIdToken);
	        var jo = JSON.parse(jsonString);

	        var tokendata = base64$decode(jo[KEY_TOKENDATA]);
	        ++tokendata[0];
	        jo[KEY_TOKENDATA] = base64$encode(tokendata);

	        UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
	            result: function() {},
	            error: function(err) { exception = err; },
	        });
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
	    runs(function() {
	        var f = function() { throw exception; };
	        expect(f).toThrow(new MslEncodingException(MslError.NONE));
	    });
    });

    it("missing signature", function() {
    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        var jsonString = JSON.stringify(userIdToken);
	        var jo = JSON.parse(jsonString);

	        expect(jo[KEY_SIGNATURE]).not.toBeNull();
	        delete jo[KEY_SIGNATURE];

	        UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
	            result: function() {},
	            error: function(err) { exception = err; },
	        });
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
	    runs(function() {
	        var f = function() { throw exception; };
	        expect(f).toThrow(new MslEncodingException(MslError.JSON_PARSE_ERROR));
	    });
    });

    it("missing renewal window", function() {
    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        var jsonString = JSON.stringify(userIdToken);
	        var jo = JSON.parse(jsonString);

	        var tokendata = base64$decode(jo[KEY_TOKENDATA]);
	        var tokendataJo = JSON.parse(textEncoding$getString(tokendata, MslConstants$DEFAULT_CHARSET));
	        expect(tokendataJo[KEY_RENEWAL_WINDOW]).not.toBeNull();
	        delete tokendataJo[KEY_RENEWAL_WINDOW];
	        jo[KEY_TOKENDATA] = base64$encode(textEncoding$getBytes(JSON.stringify(tokendataJo), MslConstants$DEFAULT_CHARSET));

	        UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
	            result: function() {},
	            error: function(err) { exception = err; },
	        });
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
	    runs(function() {
	        var f = function() { throw exception; };
	        expect(f).toThrow(new MslEncodingException(MslError.USERIDTOKEN_TOKENDATA_PARSE_ERROR));
	    });
    });

    it("invalid renewal window", function() {
    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        var jsonString = JSON.stringify(userIdToken);
	        var jo = JSON.parse(jsonString);

	        var tokendata = base64$decode(jo[KEY_TOKENDATA]);
	        var tokendataJo = JSON.parse(textEncoding$getString(tokendata, MslConstants$DEFAULT_CHARSET));
	        tokendataJo[KEY_RENEWAL_WINDOW] = "x";
	        jo[KEY_TOKENDATA] = base64$encode(textEncoding$getBytes(JSON.stringify(tokendataJo), MslConstants$DEFAULT_CHARSET));

	        UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
	            result: function() {},
	            error: function(err) { exception = err; },
	        });
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
    	runs(function() {
    	    var f = function() { throw exception; };
    	    expect(f).toThrow(new MslEncodingException(MslError.USERIDTOKEN_TOKENDATA_PARSE_ERROR));
    	});
    });

    it("missing expiration", function() {
    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        var jsonString = JSON.stringify(userIdToken);
	        var jo = JSON.parse(jsonString);

	        var tokendata = base64$decode(jo[KEY_TOKENDATA]);
	        var tokendataJo = JSON.parse(textEncoding$getString(tokendata, MslConstants$DEFAULT_CHARSET));
	        expect(tokendataJo[KEY_EXPIRATION]).not.toBeNull();
	        delete tokendataJo[KEY_EXPIRATION];
	        jo[KEY_TOKENDATA] = base64$encode(textEncoding$getBytes(JSON.stringify(tokendataJo), MslConstants$DEFAULT_CHARSET));

	        UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
	            result: function() {},
	            error: function(err) { exception = err; },
	        });
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
	    runs(function() {
	        var f = function() { throw exception; };
	        expect(f).toThrow(new MslEncodingException(MslError.USERIDTOKEN_TOKENDATA_PARSE_ERROR));
	    });
    });

    it("invalid expiration", function() {
    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        var jsonString = JSON.stringify(userIdToken);
	        var jo = JSON.parse(jsonString);

	        var tokendata = base64$decode(jo[KEY_TOKENDATA]);
	        var tokendataJo = JSON.parse(textEncoding$getString(tokendata, MslConstants$DEFAULT_CHARSET));
	        tokendataJo[KEY_EXPIRATION] = "x";
	        jo[KEY_TOKENDATA] = base64$encode(textEncoding$getBytes(JSON.stringify(tokendataJo), MslConstants$DEFAULT_CHARSET));

	        UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
	            result: function() {},
	            error: function(err) { exception = err; },
	        });
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
	    runs(function() {
	        var f = function() { throw exception; };
	        expect(f).toThrow(new MslEncodingException(MslError.USERIDTOKEN_TOKENDATA_PARSE_ERROR));
	    });
    });

    it("missing serial number", function() {
    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        var jsonString = JSON.stringify(userIdToken);
	        var jo = JSON.parse(jsonString);

	        var tokendata = base64$decode(jo[KEY_TOKENDATA]);
	        var tokendataJo = JSON.parse(textEncoding$getString(tokendata, MslConstants$DEFAULT_CHARSET));
	        expect(tokendataJo[KEY_SERIAL_NUMBER]).not.toBeNull();
	        delete tokendataJo[KEY_SERIAL_NUMBER];
	        jo[KEY_TOKENDATA] = base64$encode(textEncoding$getBytes(JSON.stringify(tokendataJo), MslConstants$DEFAULT_CHARSET));

	        UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
	            result: function() {},
	            error: function(err) { exception = err; },
	        });
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
	    runs(function() {
	        var f = function() { throw exception; };
	        expect(f).toThrow(new MslEncodingException(MslError.USERIDTOKEN_TOKENDATA_PARSE_ERROR));
	    });
    });

    it("invalid serial number", function() {
    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        var jsonString = JSON.stringify(userIdToken);
	        var jo = JSON.parse(jsonString);

	        var tokendata = base64$decode(jo[KEY_TOKENDATA]);
	        var tokendataJo = JSON.parse(textEncoding$getString(tokendata, MslConstants$DEFAULT_CHARSET));
	        tokendataJo[KEY_SERIAL_NUMBER] = "x";
	        jo[KEY_TOKENDATA] = base64$encode(textEncoding$getBytes(JSON.stringify(tokendataJo), MslConstants$DEFAULT_CHARSET));

	        UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
	            result: function() {},
	            error: function(err) { exception = err; },
	        });
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
	    runs(function() {
	        var f = function() { throw exception; };
	        expect(f).toThrow(new MslEncodingException(MslError.USERIDTOKEN_TOKENDATA_PARSE_ERROR));
	    });
    });

    it("negative serial number ctor", function() {
    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        var jsonString = JSON.stringify(userIdToken);
	        var jo = JSON.parse(jsonString);

	        var tokendata = base64$decode(jo[KEY_TOKENDATA]);
	        var tokendataJo = JSON.parse(textEncoding$getString(tokendata, MslConstants$DEFAULT_CHARSET));
	        tokendataJo[KEY_SERIAL_NUMBER] = -1;
	        jo[KEY_TOKENDATA] = base64$encode(textEncoding$getBytes(JSON.stringify(tokendataJo), MslConstants$DEFAULT_CHARSET));

	        UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
	            result: function() {},
	            error: function(err) { exception = err; },
	        });
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
	    runs(function() {
	        var f = function() { throw exception; };
	        expect(f).toThrow(new MslException(MslError.USERIDTOKEN_SERIAL_NUMBER_OUT_OF_RANGE));
	    });
    });

    it("too large serial number ctor", function() {
    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        var jsonString = JSON.stringify(userIdToken);
	        var jo = JSON.parse(jsonString);

	        var tokendata = base64$decode(jo[KEY_TOKENDATA]);
	        var tokendataJo = JSON.parse(textEncoding$getString(tokendata, MslConstants$DEFAULT_CHARSET));
	        tokendataJo[KEY_SERIAL_NUMBER] = MslConstants$MAX_LONG_VALUE + 2;
	        jo[KEY_TOKENDATA] = base64$encode(textEncoding$getBytes(JSON.stringify(tokendataJo), MslConstants$DEFAULT_CHARSET));

	        UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
	            result: function() {},
	            error: function(err) { exception = err; },
	        });
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
	    runs(function() {
	        var f = function() { throw exception; };
	        expect(f).toThrow(new MslException(MslError.USERIDTOKEN_SERIAL_NUMBER_OUT_OF_RANGE));
	    });
    });

    it("missing master token serial number", function() {
    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        var jsonString = JSON.stringify(userIdToken);
	        var jo = JSON.parse(jsonString);

	        var tokendata = base64$decode(jo[KEY_TOKENDATA]);
	        var tokendataJo = JSON.parse(textEncoding$getString(tokendata, MslConstants$DEFAULT_CHARSET));
	        expect(tokendataJo[KEY_MASTER_TOKEN_SERIAL_NUMBER]).not.toBeNull();
	        delete tokendataJo[KEY_MASTER_TOKEN_SERIAL_NUMBER];
	        jo[KEY_TOKENDATA] = base64$encode(textEncoding$getBytes(JSON.stringify(tokendataJo), MslConstants$DEFAULT_CHARSET));

	        UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
	            result: function() {},
	            error: function(err) { exception = err; },
	        });
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
	    runs(function() {
	        var f = function() { throw exception; };
	        expect(f).toThrow(new MslEncodingException(MslError.USERIDTOKEN_TOKENDATA_PARSE_ERROR));
	    });
    });

    it("invalid master token serial number", function() {
    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        var jsonString = JSON.stringify(userIdToken);
	        var jo = JSON.parse(jsonString);

	        var tokendata = base64$decode(jo[KEY_TOKENDATA]);
	        var tokendataJo = JSON.parse(textEncoding$getString(tokendata, MslConstants$DEFAULT_CHARSET));
	        tokendataJo[KEY_MASTER_TOKEN_SERIAL_NUMBER] = "x";
	        jo[KEY_TOKENDATA] = base64$encode(textEncoding$getBytes(JSON.stringify(tokendataJo), MslConstants$DEFAULT_CHARSET));

	        UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
	            result: function() {},
	            error: function(err) { exception = err; },
	        });
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
	    runs(function() {
	        var f = function() { throw exception; };
	        expect(f).toThrow(new MslEncodingException(MslError.USERIDTOKEN_TOKENDATA_PARSE_ERROR));
	    });
    });

    it("negative master token serial number ctor", function() {
    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        var jsonString = JSON.stringify(userIdToken);
	        var jo = JSON.parse(jsonString);

	        var tokendata = base64$decode(jo[KEY_TOKENDATA]);
	        var tokendataJo = JSON.parse(textEncoding$getString(tokendata, MslConstants$DEFAULT_CHARSET));
	        tokendataJo[KEY_MASTER_TOKEN_SERIAL_NUMBER] = -1;
	        jo[KEY_TOKENDATA] = base64$encode(textEncoding$getBytes(JSON.stringify(tokendataJo), MslConstants$DEFAULT_CHARSET));

	        UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
	            result: function() {},
	            error: function(err) { exception = err; },
	        });
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
	    runs(function() {
	        var f = function() { throw exception; };
	        expect(f).toThrow(new MslException(MslError.USERIDTOKEN_MASTERTOKEN_SERIAL_NUMBER_OUT_OF_RANGE));
	    });
    });

    it("too large master token serial number ctor", function() {
    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        var jsonString = JSON.stringify(userIdToken);
	        var jo = JSON.parse(jsonString);

	        var tokendata = base64$decode(jo[KEY_TOKENDATA]);
	        var tokendataJo = JSON.parse(textEncoding$getString(tokendata, MslConstants$DEFAULT_CHARSET));
	        tokendataJo[KEY_MASTER_TOKEN_SERIAL_NUMBER] = MslConstants$MAX_LONG_VALUE + 2;
	        jo[KEY_TOKENDATA] = base64$encode(textEncoding$getBytes(JSON.stringify(tokendataJo), MslConstants$DEFAULT_CHARSET));

	        UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
	            result: function() {},
	            error: function(err) { exception = err; },
	        });
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
	    runs(function() {
	        var f = function() { throw exception; };
	        expect(f).toThrow(new MslException(MslError.USERIDTOKEN_MASTERTOKEN_SERIAL_NUMBER_OUT_OF_RANGE));
	    });
    });

    it("missing userdata", function() {
    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        var jsonString = JSON.stringify(userIdToken);
	        var jo = JSON.parse(jsonString);

	        var tokendata = base64$decode(jo[KEY_TOKENDATA]);
	        var tokendataJo = JSON.parse(textEncoding$getString(tokendata, MslConstants$DEFAULT_CHARSET));
	        expect(tokendataJo[KEY_USERDATA]).not.toBeNull();
	        delete tokendataJo[KEY_USERDATA];
	        jo[KEY_TOKENDATA] = base64$encode(textEncoding$getBytes(JSON.stringify(tokendataJo), MslConstants$DEFAULT_CHARSET));

	        UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
	            result: function() {},
	            error: function(err) { exception = err; },
	        });
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
	    runs(function() {
	        var f = function() { throw exception; };
	        expect(f).toThrow(new MslEncodingException(MslError.USERIDTOKEN_TOKENDATA_PARSE_ERROR));
	    });
    });

    it("invalid userdata", function() {
    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        var jsonString = JSON.stringify(userIdToken);
	        var jo = JSON.parse(jsonString);

	        var tokendata = base64$decode(jo[KEY_TOKENDATA]);
	        var tokendataJo = JSON.parse(textEncoding$getString(tokendata, MslConstants$DEFAULT_CHARSET));
	        tokendataJo[KEY_USERDATA] = "x";

	        var cryptoContext = ctx.getMslCryptoContext();
	        var modifiedTokendata = textEncoding$getBytes(JSON.stringify(tokendataJo), MslConstants$DEFAULT_CHARSET);
	        cryptoContext.sign(modifiedTokendata, {
	        	result: function(signature) {
	        		jo[KEY_TOKENDATA] = base64$encode(modifiedTokendata);
	    	        jo[KEY_SIGNATURE] = base64$encode(signature);

	    	        UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
	    	            result: function() {},
	    	            error: function(err) { exception = err; },
	    	        });
	        	},
	        	error: function(e) { expect(function() { throw e; }).not.toThrow(); }
	        });
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
	    runs(function() {
	        var f = function() { throw exception; };
	        expect(f).toThrow(new MslException(MslError.USERIDTOKEN_USERDATA_INVALID));
	    });
    });

    it("empty userdata", function() {
    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        var jsonString = JSON.stringify(userIdToken);
	        var jo = JSON.parse(jsonString);

	        var tokendata = base64$decode(jo[KEY_TOKENDATA]);
	        var tokendataJo = JSON.parse(textEncoding$getString(tokendata, MslConstants$DEFAULT_CHARSET));

	        var cryptoContext = ctx.getMslCryptoContext();
	        var ciphertext = new Uint8Array(0);
	        tokendataJo[KEY_USERDATA] = base64$encode(ciphertext);
	        var modifiedTokendata = textEncoding$getBytes(JSON.stringify(tokendataJo), MslConstants$DEFAULT_CHARSET);
	        cryptoContext.sign(modifiedTokendata, {
	        	result: function(signature) {
	        		jo[KEY_TOKENDATA] = base64$encode(modifiedTokendata);
	    	        jo[KEY_SIGNATURE] = base64$encode(signature);

	    	        UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
	    	            result: function() {},
	    	            error: function(err) { exception = err; },
	    	        });
	        	},
	        	error: function(e) { expect(function() { throw e; }).not.toThrow(); }
	        });
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
    	runs(function() {
    	    var f = function() { throw exception; };
    	    expect(f).toThrow(new MslException(MslError.USERIDTOKEN_USERDATA_MISSING));
    	});
    });

    it("corrupt userdata", function() {
    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        var jsonString = JSON.stringify(userIdToken);
	        var jo = JSON.parse(jsonString);

	        // This is testing user data that is verified but corrupt.
	        var tokendata = base64$decode(jo[KEY_TOKENDATA]);
	        var tokendataJo = JSON.parse(textEncoding$getString(tokendata, MslConstants$DEFAULT_CHARSET));
	        var userdata = base64$decode(tokendataJo[KEY_USERDATA]);
	        ++userdata[userdata.length-1];
	        tokendataJo[KEY_USERDATA] = base64$encode(userdata);

	        var cryptoContext = ctx.getMslCryptoContext();
	        var modifiedTokendata = textEncoding$getBytes(JSON.stringify(tokendataJo), MslConstants$DEFAULT_CHARSET);
	        cryptoContext.sign(modifiedTokendata, {
	        	result: function(signature) {
	        		jo[KEY_TOKENDATA] = base64$encode(modifiedTokendata);
	    	        jo[KEY_SIGNATURE] = base64$encode(signature);

	    	        UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
	    	            result: function() {},
	    	            error: function(err) { exception = err; },
	    	        });
	        	},
	        	error: function(e) { expect(function() { throw e; }).not.toThrow(); }
	        });
    	});
    	waitsFor(function() { return exception; }, "exception not received", 100);
    	runs(function() {
    	    var f = function() { throw exception; };
    	    expect(f).toThrow(new MslCryptoException(MslError.NONE));
    	});
    });

    it("invalid user", function() {
    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        var jsonString = JSON.stringify(userIdToken);
	        var jo = JSON.parse(jsonString);

	        var cryptoContext = ctx.getMslCryptoContext();

	        // Before modifying the user data we need to decrypt it.
	        var tokendata = base64$decode(jo[KEY_TOKENDATA]);
	        var tokendataJo = JSON.parse(textEncoding$getString(tokendata, MslConstants$DEFAULT_CHARSET));
	        var ciphertext = base64$decode(tokendataJo[KEY_USERDATA]);
	        cryptoContext.decrypt(ciphertext, {
	        	result: function(plaintext) {
	        		var userdataJo = JSON.parse(textEncoding$getString(plaintext, MslConstants$DEFAULT_CHARSET));

	        		// After modifying the user data we need to encrypt it.
	        		userdataJo[KEY_IDENTITY] = {};
	        		cryptoContext.encrypt(textEncoding$getBytes(JSON.stringify(userdataJo, MslConstants$DEFAULT_CHARSET)), {
	        			result: function(userdata) {
	        				tokendataJo[KEY_USERDATA] = base64$encode(userdata);

	        				// The tokendata must be signed otherwise the user data will not be
	        				// processed.
	        				var modifiedTokendata = textEncoding$getBytes(JSON.stringify(tokendataJo), MslConstants$DEFAULT_CHARSET);
	        				cryptoContext.sign(modifiedTokendata, {
	        		        	result: function(signature) {
	        		        		jo[KEY_TOKENDATA] = base64$encode(modifiedTokendata);
	        		    	        jo[KEY_SIGNATURE] = base64$encode(signature);

	        		    	        UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
	        		    	            result: function() {},
	        		    	            error: function(err) { exception = err; },
	        		    	        });
	        		        	},
	        		        	error: function(e) { expect(function() { throw e; }).not.toThrow(); }
	        		        });
	        			},
	        			error: function(e) { expect(function() { throw e; }).not.toThrow(); }
	        		});
	        	},
	        	error: function(e) { expect(function() { throw e; }).not.toThrow(); }
	        });
        });
        waitsFor(function() { return exception; }, "exception not received", 100);
    	runs(function() {
    	    var f = function() { throw exception; };
    	    expect(f).toThrow(new MslEncodingException(MslError.USERIDTOKEN_USERDATA_PARSE_ERROR));
    	});
    });

    it("empty user", function() {
    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        var jsonString = JSON.stringify(userIdToken);
	        var jo = JSON.parse(jsonString);

	        var cryptoContext = ctx.getMslCryptoContext();

	        // Before modifying the user data we need to decrypt it.
	        var tokendata = base64$decode(jo[KEY_TOKENDATA]);
	        var tokendataJo = JSON.parse(textEncoding$getString(tokendata, MslConstants$DEFAULT_CHARSET));
	        var ciphertext = base64$decode(tokendataJo[KEY_USERDATA]);
	        cryptoContext.decrypt(ciphertext, {
	        	result: function(plaintext) {
	        		var userdataJo = JSON.parse(textEncoding$getString(plaintext, MslConstants$DEFAULT_CHARSET));

	        		// After modifying the user data we need to encrypt it.
	        		userdataJo[KEY_IDENTITY] = "";
	        		cryptoContext.encrypt(textEncoding$getBytes(JSON.stringify(userdataJo, MslConstants$DEFAULT_CHARSET)), {
	        			result: function(userdata) {
	        				tokendataJo[KEY_USERDATA] = base64$encode(userdata);

	        				// The tokendata must be signed otherwise the user data will not be
	        				// processed.
	        				var modifiedTokendata = textEncoding$getBytes(JSON.stringify(tokendataJo), MslConstants$DEFAULT_CHARSET);
	        				cryptoContext.sign(modifiedTokendata, {
	        		        	result: function(signature) {
	        		        		jo[KEY_TOKENDATA] = base64$encode(modifiedTokendata);
	        		    	        jo[KEY_SIGNATURE] = base64$encode(signature);

	        		    	        UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
	        		    	            result: function() {},
	        		    	            error: function(err) { exception = err; },
	        		    	        });
	        		        	},
	        		        	error: function(e) { expect(function() { throw e; }).not.toThrow(); }
	        		        });
	        			},
	        			error: function(e) { expect(function() { throw e; }).not.toThrow(); }
	        		});
	        	},
	        	error: function(e) { expect(function() { throw e; }).not.toThrow(); }
	        });
        });
        waitsFor(function() { return exception; }, "exception not received", 100);
    	runs(function() {
    	    var f = function() { throw exception; };
    	    expect(f).toThrow(new MslException(MslError.USERIDTOKEN_IDENTITY_INVALID));
    	});
    });

    it("missing user", function() {
    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        var jsonString = JSON.stringify(userIdToken);
	        var jo = JSON.parse(jsonString);

	        var cryptoContext = ctx.getMslCryptoContext();

	        // Before modifying the user data we need to decrypt it.
	        var tokendata = base64$decode(jo[KEY_TOKENDATA]);
	        var tokendataJo = JSON.parse(textEncoding$getString(tokendata, MslConstants$DEFAULT_CHARSET));
	        var ciphertext = base64$decode(tokendataJo[KEY_USERDATA]);
	        cryptoContext.decrypt(ciphertext, {
	        	result: function(plaintext) {
	        		var userdataJo = JSON.parse(textEncoding$getString(plaintext, MslConstants$DEFAULT_CHARSET));

	        		// After modifying the user data we need to encrypt it.
	        		delete userdataJo[KEY_IDENTITY];
	        		cryptoContext.encrypt(textEncoding$getBytes(JSON.stringify(userdataJo, MslConstants$DEFAULT_CHARSET)), {
	        			result: function(userdata) {
	        				tokendataJo[KEY_USERDATA] = base64$encode(userdata);

	        				// The tokendata must be signed otherwise the user data will not be
	        				// processed.
	        				var modifiedTokendata = textEncoding$getBytes(JSON.stringify(tokendataJo), MslConstants$DEFAULT_CHARSET);
	        				cryptoContext.sign(modifiedTokendata, {
	        		        	result: function(signature) {
	        		        		jo[KEY_TOKENDATA] = base64$encode(modifiedTokendata);
	        		    	        jo[KEY_SIGNATURE] = base64$encode(signature);

	        		    	        UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
	        		    	            result: function() {},
	        		    	            error: function(err) { exception = err; },
	        		    	        });
	        		        	},
	        		        	error: function(e) { expect(function() { throw e; }).not.toThrow(); }
	        		        });
	        			},
	        			error: function(e) { expect(function() { throw e; }).not.toThrow(); }
	        		});
	        	},
	        	error: function(e) { expect(function() { throw e; }).not.toThrow(); }
	        });
        });
        waitsFor(function() { return exception; }, "exception not received", 100);
    	runs(function() {
    	    var f = function() { throw exception; };
    	    expect(f).toThrow(new MslEncodingException(MslError.USERIDTOKEN_USERDATA_PARSE_ERROR));
    	});
    });

    it("invalid issuer data", function() {
    	var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var exception;
        runs(function() {
	        var jsonString = JSON.stringify(userIdToken);
	        var jo = JSON.parse(jsonString);

	        var cryptoContext = ctx.getMslCryptoContext();

	        // Before modifying the user data we need to decrypt it.
	        var tokendata = base64$decode(jo[KEY_TOKENDATA]);
	        var tokendataJo = JSON.parse(textEncoding$getString(tokendata, MslConstants$DEFAULT_CHARSET));
	        var ciphertext = base64$decode(tokendataJo[KEY_USERDATA]);
	        cryptoContext.decrypt(ciphertext, {
	        	result: function(plaintext) {
	        		var userdataJo = JSON.parse(textEncoding$getString(plaintext, MslConstants$DEFAULT_CHARSET));

	        		// After modifying the user data we need to encrypt it.
	        		userdataJo[KEY_ISSUER_DATA] = "x";
	        		cryptoContext.encrypt(textEncoding$getBytes(JSON.stringify(userdataJo, MslConstants$DEFAULT_CHARSET)), {
	        			result: function(userdata) {
	        				tokendataJo[KEY_USERDATA] = base64$encode(userdata);

	        				// The tokendata must be signed otherwise the user data will not be
	        				// processed.
	        				var modifiedTokendata = textEncoding$getBytes(JSON.stringify(tokendataJo), MslConstants$DEFAULT_CHARSET);
	        				cryptoContext.sign(modifiedTokendata, {
	        		        	result: function(signature) {
	        		        		jo[KEY_TOKENDATA] = base64$encode(modifiedTokendata);
	        		    	        jo[KEY_SIGNATURE] = base64$encode(signature);

	        		    	        UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
	        		    	            result: function() {},
	        		    	            error: function(err) { exception = err; },
	        		    	        });
	        		        	},
	        		        	error: function(e) { expect(function() { throw e; }).not.toThrow(); }
	        		        });
	        			},
	        			error: function(e) { expect(function() { throw e; }).not.toThrow(); }
	        		});
	        	},
	        	error: function(e) { expect(function() { throw e; }).not.toThrow(); }
	        });
        });
        waitsFor(function() { return exception; }, "exception not received", 100);
    	runs(function() {
    	    var f = function() { throw exception; };
    	    expect(f).toThrow(new MslEncodingException(MslError.USERIDTOKEN_USERDATA_PARSE_ERROR));
    	});
    });

    it("not verified", function() {
        var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);

        var jsonString = undefined, joUserIdToken;
        runs(function() {
            jsonString = JSON.stringify(userIdToken);
            var jo = JSON.parse(jsonString);

            var signature = base64$decode(jo[KEY_SIGNATURE]);
            ++signature[0];
            jo[KEY_SIGNATURE] = base64$encode(signature);

            UserIdToken$parse(ctx, jo, MASTER_TOKEN, {
                result: function(token) { joUserIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return jsonString && joUserIdToken; }, "joUserIdToken not received", 100);
        runs(function() {
	        expect(joUserIdToken.isDecrypted()).toBeFalsy();
	        expect(joUserIdToken.isVerified()).toBeFalsy();
	        expect(joUserIdToken.isRenewable(null)).not.toEqual(userIdToken.isRenewable(null));
	        expect(joUserIdToken.isExpired(null)).toEqual(userIdToken.isExpired(null));
	        expect(joUserIdToken.isBoundTo(MASTER_TOKEN)).toEqual(userIdToken.isBoundTo(MASTER_TOKEN));
	        expect(joUserIdToken.user).toBeNull();
	        expect(joUserIdToken.expiration.getTime() / MILLISECONDS_PER_SECOND).toEqual(userIdToken.expiration.getTime() / MILLISECONDS_PER_SECOND);
	        expect(joUserIdToken.mtSerialNumber).toEqual(userIdToken.mtSerialNumber);
	        expect(joUserIdToken.renewalWindow.getTime() / MILLISECONDS_PER_SECOND).toEqual(userIdToken.renewalWindow.getTime() / MILLISECONDS_PER_SECOND);
	        expect(joUserIdToken.serialNumber).toEqual(userIdToken.serialNumber);
	        var joJsonString = JSON.stringify(joUserIdToken);
	        expect(joJsonString).not.toBeNull();
	        expect(joJsonString).not.toEqual(jsonString);
        });
    });

    it("is renewable", function() {
        var renewalWindow = new Date();
        var expiration = new Date(Date.now() + 10000);
        var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, renewalWindow, expiration, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);
        runs(function() {
            var now = new Date();
	        expect(userIdToken.isRenewable(null)).toBeTruthy();
            expect(userIdToken.isRenewable(now)).toBeTruthy();
            expect(userIdToken.isExpired(null)).toBeFalsy();
	        expect(userIdToken.isExpired(now)).toBeFalsy();

            var before = new Date(renewalWindow.getTime() - 1000);
            expect(userIdToken.isRenewable(before)).toBeFalsy();
            expect(userIdToken.isExpired(before)).toBeFalsy();

            var after = new Date(expiration.getTime() + 1000);
            expect(userIdToken.isRenewable(after)).toBeTruthy();
            expect(userIdToken.isExpired(after)).toBeTruthy();
        });
    });

    it("is expired", function() {
        var renewalWindow = new Date(Date.now() - 10000);
        var expiration = new Date();
        var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, renewalWindow, expiration, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);
        runs(function() {
            var now = new Date();
	        expect(userIdToken.isRenewable(null)).toBeTruthy();
            expect(userIdToken.isRenewable(now)).toBeTruthy();
            expect(userIdToken.isExpired(null)).toBeTruthy();
	        expect(userIdToken.isExpired(now)).toBeTruthy();

            var before = new Date(renewalWindow.getTime() - 1000);
            expect(userIdToken.isRenewable(before)).toBeFalsy();
            expect(userIdToken.isExpired(before)).toBeFalsy();

            var after = new Date(expiration.getTime() + 1000);
            expect(userIdToken.isRenewable(after)).toBeTruthy();
            expect(userIdToken.isExpired(after)).toBeTruthy();
        });
    });

    it("not renewable or expired", function() {
        var renewalWindow = new Date(Date.now() + 10000);
        var expiration = new Date(Date.now() + 20000);
        var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, renewalWindow, expiration, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);
        runs(function() {
            var now = new Date();
	        expect(userIdToken.isRenewable(null)).toBeFalsy();
            expect(userIdToken.isRenewable(now)).toBeFalsy();
            expect(userIdToken.isExpired(null)).toBeFalsy();
	        expect(userIdToken.isExpired(now)).toBeFalsy();

            var before = new Date(renewalWindow.getTime() - 1000);
            expect(userIdToken.isRenewable(before)).toBeFalsy();
            expect(userIdToken.isExpired(before)).toBeFalsy();

            var after = new Date(expiration.getTime() + 1000);
            expect(userIdToken.isRenewable(after)).toBeTruthy();
            expect(userIdToken.isExpired(after)).toBeTruthy();
        });
    });

    it("is bound to master token", function() {
        var masterTokenA = undefined, masterTokenB;
        runs(function() {
        	MslTestUtils.getMasterToken(ctx, 1, 1, {
        		result: function(token) { masterTokenA = token; },
        		error: function(e) { expect(function() { throw e; }).not.toThrow(); },
        	});
        	MslTestUtils.getMasterToken(ctx, 1, 2, {
        		result: function(token) { masterTokenB = token; },
        		error: function(e) { expect(function() { throw e; }).not.toThrow(); },
        	});
        });
        waitsFor(function() { return masterTokenA && masterTokenB; }, "master tokens not received", 100);

        var userIdTokenA = undefined, userIdTokenB;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, masterTokenA, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdTokenA = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, masterTokenB, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdTokenB = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdTokenA && userIdTokenB; }, "user ID tokens not received", 100);
        runs(function() {
	        expect(userIdTokenA.isBoundTo(masterTokenA)).toBeTruthy();
	        expect(userIdTokenA.isBoundTo(masterTokenB)).toBeFalsy();
	        expect(userIdTokenA.isBoundTo(null)).toBeFalsy();
	        expect(userIdTokenB.isBoundTo(masterTokenB)).toBeTruthy();
	        expect(userIdTokenB.isBoundTo(masterTokenA)).toBeFalsy();
	        expect(userIdTokenB.isBoundTo(null)).toBeFalsy();
        });
    });

    it("equals serial number", function() {
        var serialNumberA = 1;
        var serialNumberB = 2;
        var userIdTokenA = undefined, userIdTokenB;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, serialNumberA, ISSUER_DATA, USER, {
                result: function(token) { userIdTokenA = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, serialNumberB, ISSUER_DATA, USER, {
                result: function(token) { userIdTokenB = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdTokenA && userIdTokenB; }, "user ID tokens not received", 100);
        var userIdTokenA2;
        runs(function() {
            UserIdToken$parse(ctx, JSON.parse(JSON.stringify(userIdTokenA)), MASTER_TOKEN, {
                result: function(token) { userIdTokenA2 = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdTokenA2; }, "user ID token parsed", 100);
        runs(function() {
	        expect(userIdTokenA.equals(userIdTokenA)).toBeTruthy();
	        expect(userIdTokenA.uniqueKey()).toEqual(userIdTokenA.uniqueKey());

	        expect(userIdTokenA.equals(userIdTokenB)).toBeFalsy();
	        expect(userIdTokenB.equals(userIdTokenA)).toBeFalsy();
	        expect(userIdTokenB.uniqueKey()).not.toEqual(userIdTokenA.uniqueKey());

	        expect(userIdTokenA.equals(userIdTokenA2)).toBeTruthy();
	        expect(userIdTokenA2.equals(userIdTokenA)).toBeTruthy();
	        expect(userIdTokenA2.uniqueKey()).toEqual(userIdTokenA.uniqueKey());
        });
    });

    it("equals master token serial number", function() {
        var masterTokenA = undefined, masterTokenB;
        runs(function() {
        	MslTestUtils.getMasterToken(ctx, 1, 1, {
        		result: function(token) { masterTokenA = token; },
        		error: function(e) { expect(function() { throw e; }).not.toThrow(); },
        	});
        	MslTestUtils.getMasterToken(ctx, 1, 2, {
        		result: function(token) { masterTokenB = token; },
        		error: function(e) { expect(function() { throw e; }).not.toThrow(); },
        	});
        });
        waitsFor(function() { return masterTokenA && masterTokenB; }, "master tokens not received", 100);

        var userIdTokenA = undefined, userIdTokenB;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, masterTokenA, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdTokenA = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, masterTokenB, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdTokenB = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdTokenA && userIdTokenB; }, "user ID tokens not received", 100);

        var userIdTokenA2;
        runs(function() {
            UserIdToken$parse(ctx, JSON.parse(JSON.stringify(userIdTokenA)), masterTokenA, {
                result: function(token) { userIdTokenA2 = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdTokenA2; }, "user ID token parsed", 100);
        runs(function() {
	        expect(userIdTokenA.equals(userIdTokenA)).toBeTruthy();
	        expect(userIdTokenA.uniqueKey()).toEqual(userIdTokenA.uniqueKey());

	        expect(userIdTokenA.equals(userIdTokenB)).toBeFalsy();
	        expect(userIdTokenB.equals(userIdTokenA)).toBeFalsy();
	        expect(userIdTokenB.uniqueKey()).not.toEqual(userIdTokenA.uniqueKey());

	        expect(userIdTokenA.equals(userIdTokenA2)).toBeTruthy();
	        expect(userIdTokenA2.equals(userIdTokenA)).toBeTruthy();
	        expect(userIdTokenA2.uniqueKey()).toEqual(userIdTokenA.uniqueKey());
        });
    });

    it("equals object", function() {
        var userIdToken;
        runs(function() {
            UserIdToken$create(ctx, RENEWAL_WINDOW, EXPIRATION, MASTER_TOKEN, SERIAL_NUMBER, ISSUER_DATA, USER, {
                result: function(token) { userIdToken = token; },
                error: function(e) { expect(function() { throw e; }).not.toThrow(); }
            });
        });
        waitsFor(function() { return userIdToken; }, "userIdToken not received", 100);
        runs(function() {
	        expect(userIdToken.equals(null)).toBeFalsy();
	        expect(userIdToken.equals(RENEWAL_WINDOW)).toBeFalsy();
        });
    });
});


text:
import { mergeWith } from "../fp";
export = mergeWith;

redpajama_set_name: RedPajamaGithub


text:
/**
 * Classes and annotations related to configuring Spring's {@code ApplicationContext} for
 * tests.
 */
package org.springframework.boot.test.context;


text:
package org.helianto.security.service;

import java.util.Date;
import java.util.List;

import javax.inject.Inject;

import org.helianto.security.domain.IdentitySecret;
import org.helianto.security.internal.AbstractDetailsService;
import org.helianto.security.internal.UserDetailsAdapter;
import org.helianto.user.domain.User;
import org.helianto.user.repository.UserReadAdapter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * Return an UserDetails instance.
 *
 * @author mauriciofernandesdecastro
 */
@Service("userDetailsService")
@Qualifier("default")
public class UserDetailsServiceImpl
	extends AbstractDetailsService
	implements UserDetailsService
{

	@Inject
	private AuthorizationChecker authorizationChecker;

	@Transactional
	public UserDetails loadUserByUsername(String userKey) throws UsernameNotFoundException, DataAccessException {

		IdentitySecret identitySecret = loadIdentitySecretByKey(userKey);
		List<UserReadAdapter> userAdapterList = loadUserListByIdentityId(identitySecret.getIdentity().getId());

		if (userAdapterList!=null && userAdapterList.size()>0) {
			// first userId in the list is the last logged one
			UserReadAdapter userReadAdapter = userAdapterList.get(0);
			UserDetailsAdapter userDetails = new UserDetailsAdapter(userReadAdapter, identitySecret);

			// update the last event date
			User user = (User) userGroupRepository.findOne(userReadAdapter.getUserId());
			user.setLastEvent(new Date());
			user = userGroupRepository.saveAndFlush(user);

			// grant the roles
			return authorizationChecker.updateAuthorities(userDetails);
		}
		else {
			logger.info("User list has no valid users.");
		}
		throw new UsernameNotFoundException("Unable to extract valid user from a list.");
	}

}


text:
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LINE_LINE_WIDTH_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LINE_LINE_WIDTH_H_

#include "third_party/blink/renderer/core/layout/api/line_layout_block_flow.h"
#include "third_party/blink/renderer/platform/geometry/layout_unit.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"

namespace blink {

class FloatingObject;
class LineLayoutRubyRun;

enum WhitespaceTreatment { kExcludeWhitespace, kIncludeWhitespace };

class LineWidth {
  STACK_ALLOCATED();

 public:
  LineWidth(LineLayoutBlockFlow, bool is_first_line, IndentTextOrNot);

  bool FitsOnLine() const {
    return LayoutUnit::FromFloatFloor(CurrentWidth()) <=
           available_width_ + LayoutUnit::Epsilon();
  }
  bool FitsOnLine(float extra) const {
    float total_width = CurrentWidth() + extra;
    return LayoutUnit::FromFloatFloor(total_width) <=
           available_width_ + LayoutUnit::Epsilon();
  }
  bool FitsOnLine(float extra, WhitespaceTreatment whitespace_treatment) const {
    LayoutUnit w = LayoutUnit::FromFloatFloor(CurrentWidth() + extra);
    if (whitespace_treatment == kExcludeWhitespace)
      w -= LayoutUnit::FromFloatCeil(TrailingWhitespaceWidth());
    return w <= available_width_;
  }

  // Note that m_uncommittedWidth may not be LayoutUnit-snapped at this point.
  // Because currentWidth() is used by the code that lays out words in a single
  // LayoutText, it's expected that offsets will not be snapped until an
  // InlineBox boundary is reached.
  float CurrentWidth() const { return committed_width_ + uncommitted_width_; }

  // FIXME: We should eventually replace these three functions by ones that work
  // on a higher abstraction.
  float UncommittedWidth() const { return uncommitted_width_; }
  float CommittedWidth() const { return committed_width_; }
  float AvailableWidth() const { return available_width_; }
  float TrailingWhitespaceWidth() const { return trailing_whitespace_width_; }

  void UpdateAvailableWidth(LayoutUnit minimum_height = LayoutUnit());
  void ShrinkAvailableWidthForNewFloatIfNeeded(const FloatingObject&);
  void AddUncommittedWidth(float delta) { uncommitted_width_ += delta; }
  void Commit();
  void ApplyOverhang(LineLayoutRubyRun,
                     LineLayoutItem start_layout_item,
                     LineLayoutItem end_layout_item);
  void FitBelowFloats(bool is_first_line = false);
  void SetTrailingWhitespaceWidth(float width) {
    trailing_whitespace_width_ = width;
  }
  void SnapAtNodeBoundary() {
    if (!uncommitted_width_) {
      committed_width_ = LayoutUnit::FromFloatCeil(committed_width_).ToFloat();
    } else {
      uncommitted_width_ =
          LayoutUnit::FromFloatCeil(committed_width_ + uncommitted_width_)
              .ToFloat() -
          committed_width_;
    }
  }

  IndentTextOrNot IndentText() const { return indent_text_; }

 private:
  void ComputeAvailableWidthFromLeftAndRight();
  void UpdateLineDimension(LayoutUnit new_line_top,
                           LayoutUnit new_line_width,
                           const LayoutUnit& new_line_left,
                           const LayoutUnit& new_line_right);
  void WrapNextToShapeOutside(bool is_first_line);

  LineLayoutBlockFlow block_;
  float uncommitted_width_;
  float committed_width_;
  // The amount by which |m_availableWidth| has been inflated to account for
  // possible contraction due to ruby overhang.
  float overhang_width_;
  float trailing_whitespace_width_;
  LayoutUnit left_;
  LayoutUnit right_;
  LayoutUnit available_width_;
  bool is_first_line_;
  IndentTextOrNot indent_text_;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LINE_LINE_WIDTH_H_


text:
package com.github.ksouf.bankaccountkata.domain;

@FunctionalInterface
public interface Printer {
    void print(String contentToPrint);
}


text:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center" >

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="8dip"
            android:orientation="vertical" >

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:singleLine="true"
                android:text="@string/network_orange"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:textColor="@color/orange_network_color1" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:singleLine="true"
                android:text="@string/network_free_mobile"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:textColor="@color/free_mobile_network_color1" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="fill_parent"
            android:gravity="center|right"
            android:orientation="vertical" >

            <TextView
                android:id="@+id/on_orange_network"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="87%"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:textColor="@color/orange_network_color1" />

            <TextView
                android:id="@+id/on_free_mobile_network"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="13%"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:textColor="@color/free_mobile_network_color1" />
        </LinearLayout>

        <org.pixmob.freemobile.netstat.ui.MobileNetworkChart
            android:id="@+id/mobile_network_chart"
            android:layout_width="@dimen/network_pie_width"
            android:layout_height="@dimen/network_pie_width"
            android:layout_marginLeft="8dip" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dip"
        android:baselineAligned="false"
        android:orientation="horizontal" >

        <LinearLayout
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:orientation="vertical" >

            <TextView
                style="@style/stat_row_even"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="@string/stat_mobile_network" />

            <TextView
                style="@style/stat_row"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="@string/stat_mobile_code" />

            <TextView
                style="@style/stat_row_even"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="@string/stat_on_orange" />

            <TextView
                style="@style/stat_row"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="@string/stat_on_free_mobile" />

            <TextView
                style="@style/stat_row_even"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="@string/stat_screen" />

            <TextView
                style="@style/stat_row"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="@string/stat_wifi" />

            <TextView
                style="@style/stat_row_even"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="@string/stat_battery" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:orientation="vertical" >

            <TextView
                android:id="@+id/stat_mobile_network"
                style="@style/stat_row_even"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="Orange" />

            <TextView
                android:id="@+id/stat_mobile_code"
                style="@style/stat_row"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="20810" />

            <TextView
                android:id="@+id/stat_on_orange"
                style="@style/stat_row_even"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="8h 14m" />

            <TextView
                android:id="@+id/stat_on_free_mobile"
                style="@style/stat_row"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="12m" />

            <TextView
                android:id="@+id/stat_screen"
                style="@style/stat_row_even"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="1h 27m" />

            <TextView
                android:id="@+id/stat_wifi"
                style="@style/stat_row"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="27m" />

            <TextView
                android:id="@+id/stat_battery"
                style="@style/stat_row_even"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="74%" />
        </LinearLayout>
    </LinearLayout>

</LinearLayout>


text:
package ictk.boardgame.io;

import java.io.IOException;
import java.io.Reader;
import java.io.BufferedReader;

import ictk.boardgame.IllegalMoveException;
import ictk.boardgame.AmbiguousMoveException;
import ictk.boardgame.Game;
import ictk.boardgame.GameInfo;
import ictk.boardgame.History;
import ictk.boardgame.Board;

/* GameReader ***************************************************************/
/** reads games in various notations.
 */
public abstract class GameReader extends BufferedReader {

   public GameReader (Reader _ir) {
      super(_ir);
   }

   /** read the Game (History, Board, and GameInfo) from the input Buffer
    */
   public abstract Game readGame ()
          throws InvalidGameFormatException,
                 IllegalMoveException,
                 AmbiguousMoveException,
                 IOException;

   /** read the GameInfo from the input buffer
    */
   public abstract GameInfo readGameInfo ()
          throws IOException;

   /** read the game History from the input buffer
    */
   public abstract History readHistory ()
          throws InvalidGameFormatException,
                 IllegalMoveException,
                 AmbiguousMoveException,
                 IOException;

   /** read the game Board from the input buffer
    */
   public abstract Board readBoard ()
          throws IOException;

}


text:
import os
import percy
import pytest
import sys

class BaseTestPercyEnvironment(object):
    def setup_method(self, method):
        self.original_env = {}
        self.original_env['TRAVIS_BUILD_ID'] = os.getenv('TRAVIS_BUILD_ID', None)
        self.original_env['TRAVIS_BUILD_NUMBER'] = os.getenv('TRAVIS_BUILD_NUMBER', None)
        self.original_env['TRAVIS_COMMIT'] = os.getenv('TRAVIS_COMMIT', None)
        self.original_env['TRAVIS_BRANCH'] = os.getenv('TRAVIS_BRANCH', None)
        self.original_env['TRAVIS_PULL_REQUEST'] = os.getenv('TRAVIS_PULL_REQUEST', None)
        self.original_env['TRAVIS_PULL_REQUEST_BRANCH'] = os.getenv('TRAVIS_PULL_REQUEST_BRANCH', None)

    def teardown_method(self, method):
        self.clear_env_vars()

        # Restore the original environment variables.
        for key, value in self.original_env.items():
            if value:
                os.environ[key] = value

    def clear_env_vars(self):
        all_possible_env_vars = [
            # Unset Percy vars.
            'PERCY_COMMIT',
            'PERCY_BRANCH',
            'PERCY_TARGET_BRANCH',
            'PERCY_TARGET_COMMIT',
            'PERCY_PULL_REQUEST',
            'PERCY_PARALLEL_NONCE',
            'PERCY_PARALLEL_TOTAL',

            # Unset Travis vars.
            'TRAVIS_BUILD_ID',
            'TRAVIS_BUILD_NUMBER',
            'TRAVIS_COMMIT',
            'TRAVIS_BRANCH',
            'TRAVIS_PULL_REQUEST',
            'TRAVIS_PULL_REQUEST_BRANCH',
            'CI_NODE_TOTAL',

            # Unset Jenkins vars.
            'JENKINS_URL',
            'BUILD_NUMBER',
            'ghprbPullId',
            'ghprbActualCommit',
            'ghprbSourceBranch',
            'GIT_COMMIT',

            # Unset Circle CI vars.
            'CIRCLECI',
            'CIRCLE_SHA1',
            'CIRCLE_BRANCH',
            'CIRCLE_BUILD_NUM',
            'CIRCLE_WORKFLOW_WORKSPACE_ID',
            'CI_PULL_REQUESTS',
            'CIRCLE_NODE_TOTAL',

            # Unset Codeship vars.
            'CI_NAME',
            'CI_BRANCH',
            'CI_PULL_REQUEST',
            'CI_COMMIT_ID',
            'CI_BUILD_NUMBER',
            'CI_BUILD_ID',
            'CI_NODE_TOTAL',

            # Unset Drone vars.
            'CI',
            'DRONE',
            'DRONE_COMMIT',
            'DRONE_BRANCH',
            'CI_PULL_REQUEST',

            # Unset Semaphore CI vars
            'CI',
            'SEMAPHORE',
            'REVISION',
            'BRANCH_NAME',
            'SEMAPHORE_BRANCH_ID',
            'SEMAPHORE_BUILD_NUMBER',
            'SEMAPHORE_CURRENT_THREAD',
            'SEMAPHORE_THREAD_COUNT',
            'PULL_REQUEST_NUMBER',

            # Unset Buildkite vars
            'BUILDKITE',
            'BUILDKITE_COMMIT',
            'BUILDKITE_BRANCH',
            'BUILDKITE_PULL_REQUEST',
            'BUILDKITE_BUILD_ID',
            'BUILDKITE_PARALLEL_JOB_COUNT',

            # Unset GitLab vars
            'GITLAB_CI',
            'CI_COMMIT_SHA',
            'CI_COMMIT_REF_NAME',
            'CI_JOB_ID',
            'CI_JOB_STAGE',
        ]
        for env_var in all_possible_env_vars:
            if os.getenv(env_var):
                del os.environ[env_var]

class TestNoEnvironment(BaseTestPercyEnvironment):
    def setup_method(self, method):
        super(TestNoEnvironment, self).setup_method(self)
        self.environment = percy.Environment()

    def test_current_ci(self):
        assert self.environment.current_ci == None

    def test_target_branch(self):
        assert self.environment.target_branch == None
        # Can be overridden with PERCY_TARGET_BRANCH.
        os.environ['PERCY_TARGET_BRANCH'] = 'staging'
        assert self.environment.target_branch == 'staging'

    def test_target_commit_sha(self):
        assert self.environment.target_commit_sha == None
        # Can be overridden with PERCY_TARGET_COMMIT.
        os.environ['PERCY_TARGET_COMMIT'] = 'test-target-commit'
        assert self.environment.target_commit_sha == 'test-target-commit'

    def test_pull_request_number(self):
        assert self.environment.pull_request_number == None
        # Can be overridden with PERCY_PULL_REQUEST.
        os.environ['PERCY_PULL_REQUEST'] = '1234'
        assert self.environment.pull_request_number == '1234'

    def test_commit_live(self, monkeypatch):
        def isstr(s):
            if sys.version_info >= (3,0):
                return isinstance(s, str)
            else:
                return isinstance(s, basestring)

        # Call commit using the real _raw_commit_data, which calls git underneath, so allow full
        # commit object with attributes containing any string. (Real data changes with each commit)
        commit_data = self.environment.commit_data
        assert isstr(commit_data['branch'])
        assert isstr(commit_data['sha'])
        assert isstr(commit_data['message'])
        assert isstr(commit_data['committed_at'])
        assert isstr(commit_data['author_name'])
        assert isstr(commit_data['author_email'])
        assert isstr(commit_data['committer_name'])
        assert isstr(commit_data['committer_email'])

    @pytest.fixture()
    def test_commit_with_failed_raw_commit(self, monkeypatch):
        # Call commit using faking a _raw_commit_data failure.
        # If git command fails, only data from environment variables.
        os.environ['PERCY_COMMIT'] = 'testcommitsha'
        os.environ['PERCY_BRANCH'] = 'testbranch'
        monkeypatch.setattr(self.environment, '_raw_commit_output', lambda x: '')
        assert self.environment.commit_data == {
            'branch': 'testbranch',
            'author_email': None,
            'author_name': None,
            'committer_email': None,
            'committer_name': None,
            'sha': 'testcommitsha',
        }
        self.clear_env_vars()

    @pytest.fixture()
    def test_commit_with_mocked_raw_commit(self, monkeypatch):
        # Call commit with _raw_commit_data returning mock data, so we can confirm it
        # gets formatted correctly
        os.environ['PERCY_BRANCH'] = 'the-coolest-branch'
        def fake_raw_commit(commit_sha):
            return """COMMIT_SHA:2fcd1b107aa25e62a06de7782d0c17544c669d139
                      AUTHOR_NAME:Tim Haines
                      AUTHOR_EMAIL:timhaines@example.com
                      COMMITTER_NAME:Other Tim Haines
                      COMMITTER_EMAIL:othertimhaines@example.com
                      COMMITTED_DATE:2018-03-10 14:41:02 -0800
                      COMMIT_MESSAGE:This is a great commit"""

        monkeypatch.setattr(self.environment, '_raw_commit_output', fake_raw_commit)
        assert self.environment.commit_data == {
            'branch': 'the-coolest-branch',
            'sha': '2fcd1b107aa25e62a06de7782d0c17544c669d139',
            'committed_at': '2018-03-10 14:41:02 -0800',
            'message': 'This is a great commit',
            'author_name': 'Tim Haines',
            'author_email': 'timhaines@example.com',
            'committer_name': 'Other Tim Haines',
            'committer_email': 'othertimhaines@example.com'
        }

    @pytest.fixture()
    def test_branch(self, monkeypatch):
        # Default calls _raw_branch_output and call git underneath, so allow any non-empty string.
        assert len(self.environment.branch) > 0

        # If git command fails, falls back to None and prints warning.
        monkeypatch.setattr(self.environment, '_raw_branch_output', lambda: '')
        assert self.environment.branch == None

        # Can be overridden with PERCY_BRANCH.
        os.environ['PERCY_BRANCH'] = 'foo'
        assert self.environment.branch == 'foo'

    def test_commit_sha(self):
        assert not self.environment.commit_sha
        # Can be overridden with PERCY_COMMIT.
        os.environ['PERCY_COMMIT'] = 'commit-sha'
        assert self.environment.commit_sha == 'commit-sha'

    def test_parallel_nonce(self):
        os.environ['PERCY_PARALLEL_NONCE'] = 'foo'
        assert self.environment.parallel_nonce == 'foo'

    def test_parallel_total(self):
        os.environ['PERCY_PARALLEL_TOTAL'] = '2'
        assert self.environment.parallel_total_shards == 2

class TestTravisEnvironment(BaseTestPercyEnvironment):
    def setup_method(self, method):
        super(TestTravisEnvironment, self).setup_method(self)
        os.environ['TRAVIS_BUILD_ID'] = '1234'
        os.environ['TRAVIS_BUILD_NUMBER'] = 'travis-build-number'
        os.environ['TRAVIS_PULL_REQUEST'] = 'false'
        os.environ['TRAVIS_PULL_REQUEST_BRANCH'] = 'false'
        os.environ['TRAVIS_COMMIT'] = 'travis-commit-sha'
        os.environ['TRAVIS_BRANCH'] = 'travis-branch'
        os.environ['CI_NODE_TOTAL'] = '3'
        self.environment = percy.Environment()

    def test_current_ci(self):
        assert self.environment.current_ci == 'travis'

    def test_pull_request_number(self):
        assert self.environment.pull_request_number == None

        os.environ['TRAVIS_PULL_REQUEST'] = '256'
        assert self.environment.pull_request_number == '256'

        # PERCY env vars should take precendence over CI. Checked here once, assume other envs work.
        os.environ['PERCY_PULL_REQUEST'] = '1234'
        assert self.environment.pull_request_number == '1234'

    def test_branch(self):
        assert self.environment.branch == 'travis-branch'

        # Triggers special path if PR build in Travis.
        os.environ['TRAVIS_PULL_REQUEST'] = '256'
        os.environ['TRAVIS_PULL_REQUEST_BRANCH'] = 'travis-pr-branch'
        assert self.environment.branch == 'travis-pr-branch'

        os.environ['PERCY_BRANCH'] = 'foo'
        assert self.environment.branch == 'foo'

    def test_commit_sha(self):
        assert self.environment.commit_sha == 'travis-commit-sha'

        os.environ['PERCY_COMMIT'] = 'commit-sha'
        assert self.environment.commit_sha == 'commit-sha'

    def test_parallel_nonce(self):
        assert self.environment.parallel_nonce == 'travis-build-number'

        os.environ['PERCY_PARALLEL_NONCE'] = 'nonce'
        assert self.environment.parallel_nonce == 'nonce'

    def test_parallel_total(self):
        assert self.environment.parallel_total_shards == 3

        os.environ['CI_NODE_TOTAL'] = ''
        assert self.environment.parallel_total_shards == None

        os.environ['PERCY_PARALLEL_TOTAL'] = '1'
        assert self.environment.parallel_total_shards == 1

class TestJenkinsEnvironment(BaseTestPercyEnvironment):
    def setup_method(self, method):
        super(TestJenkinsEnvironment, self).setup_method(self)
        os.environ['JENKINS_URL'] = 'http://localhost:8080/'
        os.environ['BUILD_NUMBER'] = 'jenkins-build-number'
        os.environ['ghprbSourceBranch'] = 'jenkins-source-branch'
        os.environ['ghprbActualCommit'] = 'jenkins-commit-sha'
        os.environ['GIT_COMMIT'] = 'jenkins-commit-sha-from-git-plugin'
        self.environment = percy.Environment()

    def test_current_ci(self):
        assert self.environment.current_ci == 'jenkins'

    def test_pull_request_number(self):
        assert self.environment.pull_request_number == None

        os.environ['ghprbPullId'] = '256'
        assert self.environment.pull_request_number == '256'

    def test_branch(self):
        assert self.environment.branch == 'jenkins-source-branch'

    def test_commit_sha(self):
        assert self.environment.commit_sha == 'jenkins-commit-sha'
        del os.environ['ghprbActualCommit']
        assert self.environment.commit_sha == 'jenkins-commit-sha-from-git-plugin'

    def test_parallel_nonce(self):
        assert self.environment.parallel_nonce == 'jenkins-build-number'

    def test_parallel_total(self):
        assert self.environment.parallel_total_shards is None

class TestCircleEnvironment(BaseTestPercyEnvironment):
    def setup_method(self, method):
        super(TestCircleEnvironment, self).setup_method(self)
        os.environ['CIRCLECI'] = 'true'
        os.environ['CIRCLE_BRANCH'] = 'circle-branch'
        os.environ['CIRCLE_SHA1'] = 'circle-commit-sha'
        os.environ['CIRCLE_BUILD_NUM'] = 'circle-build-number'
        os.environ['CIRCLE_WORKFLOW_WORKSPACE_ID'] = 'circle-workflow-workspace-id'
        os.environ['CIRCLE_NODE_TOTAL'] = '3'
        os.environ['CI_PULL_REQUESTS'] = 'https://github.com/owner/repo-name/pull/123'
        self.environment = percy.Environment()

    def test_current_ci(self):
        assert self.environment.current_ci == 'circle'

    def test_branch(self):
        assert self.environment.branch == 'circle-branch'

    def test_commit_sha(self):
        assert self.environment.commit_sha == 'circle-commit-sha'

    def test_parallel_nonce(self):
        assert self.environment.parallel_nonce == 'circle-workflow-workspace-id'
        del os.environ['CIRCLE_WORKFLOW_WORKSPACE_ID']
        assert self.environment.parallel_nonce == 'circle-build-number'

    def test_parallel_total(self):
        assert self.environment.parallel_total_shards == 3

class TestCodeshipEnvironment(BaseTestPercyEnvironment):
    def setup_method(self, method):
        super(TestCodeshipEnvironment, self).setup_method(self)
        os.environ['CI_NAME'] = 'codeship'
        os.environ['CI_BRANCH'] = 'codeship-branch'
        os.environ['CI_BUILD_NUMBER'] = 'codeship-build-number'
        os.environ['CI_BUILD_ID'] = 'codeship-build-id'
        os.environ['CI_PULL_REQUEST'] = 'false'  # This is always false on Codeship, unfortunately.
        os.environ['CI_COMMIT_ID'] = 'codeship-commit-sha'
        os.environ['CI_NODE_TOTAL'] = '3'
        self.environment = percy.Environment()

    def test_current_ci(self):
        assert self.environment.current_ci == 'codeship'

    def test_branch(self):
        assert self.environment.branch == 'codeship-branch'

    def test_commit_sha(self):
        assert self.environment.commit_sha == 'codeship-commit-sha'

    def test_parallel_nonce(self):
        assert self.environment.parallel_nonce == 'codeship-build-number'
        del os.environ['CI_BUILD_NUMBER']
        assert self.environment.parallel_nonce == 'codeship-build-id'

    def test_parallel_total(self):
        assert self.environment.parallel_total_shards == 3

class TestDroneEnvironment(BaseTestPercyEnvironment):
    def setup_method(self, method):
        super(TestDroneEnvironment, self).setup_method(self)
        os.environ['DRONE'] = 'true'
        os.environ['DRONE_COMMIT'] = 'drone-commit-sha'
        os.environ['DRONE_BRANCH'] = 'drone-branch'
        os.environ['CI_PULL_REQUEST'] = '123'
        self.environment = percy.Environment()

    def test_current_ci(self):
        assert self.environment.current_ci == 'drone'

    def test_branch(self):
        assert self.environment.branch == 'drone-branch'

    def test_commit_sha(self):
        assert self.environment.commit_sha == 'drone-commit-sha'

    def test_parallel_nonce(self):
        assert self.environment.parallel_nonce is None

    def test_parallel_total(self):
        assert self.environment.parallel_total_shards is None

class TestSemaphoreEnvironment(BaseTestPercyEnvironment):
    def setup_method(self, method):
        super(TestSemaphoreEnvironment, self).setup_method(self)
        os.environ['SEMAPHORE'] = 'true'
        os.environ['BRANCH_NAME'] = 'semaphore-branch'
        os.environ['REVISION'] = 'semaphore-commit-sha'
        os.environ['SEMAPHORE_BRANCH_ID'] = 'semaphore-branch-id'
        os.environ['SEMAPHORE_BUILD_NUMBER'] = 'semaphore-build-number'
        os.environ['SEMAPHORE_THREAD_COUNT'] = '2'
        os.environ['PULL_REQUEST_NUMBER'] = '123'
        self.environment = percy.Environment()

    def test_current_ci(self):
        assert self.environment.current_ci == 'semaphore'

    def test_branch(self):
        assert self.environment.branch == 'semaphore-branch'

    def test_commit_sha(self):
        assert self.environment.commit_sha == 'semaphore-commit-sha'

    def test_parallel_nonce(self):
        expected_nonce = 'semaphore-branch-id/semaphore-build-number'
        assert self.environment.parallel_nonce == expected_nonce

    def test_parallel_total(self):
        assert self.environment.parallel_total_shards == 2

class TestBuildkiteEnvironment(BaseTestPercyEnvironment):
    def setup_method(self, method):
        super(TestBuildkiteEnvironment, self).setup_method(self)
        os.environ['BUILDKITE'] = 'true'
        os.environ['BUILDKITE_COMMIT'] = 'buildkite-commit-sha'
        os.environ['BUILDKITE_BRANCH'] = 'buildkite-branch'
        os.environ['BUILDKITE_PULL_REQUEST'] = 'false'
        os.environ['BUILDKITE_BUILD_ID'] = 'buildkite-build-id'
        os.environ['BUILDKITE_PARALLEL_JOB_COUNT'] = '2'
        self.environment = percy.Environment()

    def test_current_ci(self):
        assert self.environment.current_ci == 'buildkite'

    def test_branch(self):
        assert self.environment.branch == 'buildkite-branch'

    def test_commit_sha(self):
        assert self.environment.commit_sha == 'buildkite-commit-sha'
        os.environ['BUILDKITE_COMMIT'] = 'HEAD'
        assert self.environment.commit_sha is None

    def test_parallel_nonce(self):
        assert self.environment.parallel_nonce == 'buildkite-build-id'

    def test_parallel_total(self):
        assert self.environment.parallel_total_shards == 2

class TestGitlabEnvironment(BaseTestPercyEnvironment):
    def setup_method(self, method):
        super(TestGitlabEnvironment, self).setup_method(self)
        os.environ['GITLAB_CI'] = 'true'
        os.environ['CI_COMMIT_SHA'] = 'gitlab-commit-sha'
        os.environ['CI_COMMIT_REF_NAME'] = 'gitlab-branch'
        os.environ['CI_JOB_ID'] = 'gitlab-job-id'
        os.environ['CI_JOB_STAGE'] = 'test'
        self.environment = percy.Environment()

    def test_current_ci(self):
        assert self.environment.current_ci == 'gitlab'

    def test_branch(self):
        assert self.environment.branch == 'gitlab-branch'

    def test_commit_sha(self):
        assert self.environment.commit_sha == 'gitlab-commit-sha'

    def test_parallel_nonce(self):
        assert self.environment.parallel_nonce == 'gitlab-branch/gitlab-job-id'


text:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Model_cs extends CI_Model {

var $column_order = array(null, 'customer_account_id','customer_name','customer_phone_number','customer_address','customer_email'); //set column field database for datatable orderable
  var $column_search = array('customer_account_id','customer_name','customer_phone_number','customer_address','customer_email'); //set column field database for datatable searchable
  var $order = array('customer_account_id' => 'asc'); // default order

  public function __construct(){
  parent::__construct();
  }

  public function getCustomers(){
    $query = $this->db->query("select * from tbl_customer ORDER BY customer_account_id asc");
    return $query;
  }

  // untuk datatables
  private function _get_datatables_query()
  {

    $this->db->select('*');
        $this->db->from('tbl_customer');

        // $this->db->get();

    $i = 0;

    foreach ($this->column_search as $item) // loop column
    {
      if($_POST['search']['value']) // if datatable send POST for search
      {

        if($i===0) // first loop
        {
          $this->db->group_start(); // open bracket. query Where with OR clause better with bracket. because maybe can combine with other WHERE with AND.
          $this->db->like($item, $_POST['search']['value']);
        }
        else
        {
          $this->db->or_like($item, $_POST['search']['value']);
        }

        if(count($this->column_search) - 1 == $i) //last loop
          $this->db->group_end(); //close bracket
      }
      $i++;
    }

    if(isset($_POST['order'])) // here order processing
    {
      $this->db->order_by($this->column_order[$_POST['order']['0']['column']], $_POST['order']['0']['dir']);
    }
    else if(isset($this->order))
    {
      $order = $this->order;
      $this->db->order_by(key($order), $order[key($order)]);
    }
  }

  function get_datatables()
  {
    $this->_get_datatables_query();
    if($_POST['length'] != -1)
    $this->db->limit($_POST['length'], $_POST['start']);
    $query = $this->db->get();
    return $query->result();
  }

  function count_filtered()
  {
    $this->_get_datatables_query();
    $query = $this->db->get();
    return $query->num_rows();
  }

  public function count_all()
  {
    $this->db->select('*');
        $this->db->from('tbl_customer');
    return $this->db->count_all_results();
  }

  public function getcustomerID($id)
  {
    $query = $this->db->query("select * from tbl_customer where customer_id='".$id."'");
    return $query;
  }

  public function push_customers($id,$data)
  {
    $this->db->where('customer_id',$id);
    $this->db->update('tbl_customer',$data);
  }
}