if(String.prototype.replaceAll == null){
	String.prototype.replaceAll = function(value, replacement){
		return this.replace(new RegExp(value, "g"), replacement);
	};
}

if(String.prototype.reverse == null){
	String.prototype.reverse = function(){
		return this.split("").reverse().join("");
	};
}

if(String.prototype.replaceSpecialChars == null){
	String.specialCharsTable =
		{ "â":"a", "á":"a", "à":"a", "ä":"a", "ã":"a", "å":"a",
		  "ê":"e", "é":"e", "è":"e", "ë":"e",
		  "î":"i", "í":"i", "ì":"i", "ï":"i",
		  "ô":"o", "ó":"o", "ò":"o", "ö":"o",
		  "û":"u", "ú":"u", "ù":"u", "ü":"u",
		  "ç":"c", "ñ":"n" };
	
	String.prototype.prepareSpecialCharsSearch = function(){
		var map = String.specialCharsTable;
		var allTerms = [this];

		for(var k in map){
			var repTerm = this.replace(map[k], k);
			if(repTerm != this){
				allTerms.push(repTerm);
				allTerms.push(repTerm.toUpperCase());

				var repTerm2 = repTerm.replace(map[k], k);
				if(repTerm2 != repTerm){
					allTerms.push(repTerm2);
					allTerms.push(repTerm2.toUpperCase());
				}
			}

			var inverted = this.reverse();
			repInvertedTerm = inverted.replace(map[k], k);
			if(repInvertedTerm != inverted){
				repInvertedTerm = repInvertedTerm.reverse();
				allTerms.push(repInvertedTerm);
				allTerms.push(repInvertedTerm.toUpperCase());
			}
		}

		return allTerms.join("|");
	};

	String.prototype.replaceSpecialChars = function(){
		var map = String.specialCharsTable;
		var value = this.toLowerCase();
		for(var k in map){
			value = value.replace(k, map[k]);
		}
		return value;
	};
}

if(String.isEmpty == null){
	String.isEmpty = function(str){
		return str == null || (Object.isString(str) && str.blank());
	};
}

if(String.isNotEmpty == null){
	String.isNotEmpty = function(str){
		return str != null && Object.isString(str) && !str.blank();
	};
}

if(String.stripToEmpty == null){
	String.stripToEmpty = function(str){
		return String.isEmpty(str) ? "" : (str||"").strip();
	};
}

if(String.repeat == null){
	String.repeat = function(str, times){
		if(String.isEmpty(str) || times <= 0) return "";

		var value = [];
		while(times-- > 0){
			value.push(str);
		}

		return value.join("");
	};
}

if(String.prototype.repeat == null){
	String.prototype.repeat = function(times){
		return String.repeat(this, times);
	}
}


if(Array.isEmpty == null){
	Array.isEmpty = function(array){
		return array == null || (Object.isArray(array) && array.length == 0);
	};
}

if(Array.isNotEmpty == null){
	Array.isNotEmpty = function(array){
		return Object.isArray(array) && array.length > 0;
	};
}

if(Date.SUNDAY == null){
	Date.SUNDAY = 0;
	Date.MONDAY = 1;
	Date.TUESDAY = 2;
	Date.WEDNESDAY = 3;
	Date.THURSDAY = 4;
	Date.FRIDAY = 5;
	Date.SATURDAY = 6;
}

if(Date.parse_DDMMYYYY == null){
	Date.parse_DDMMYYYY = function(value, time){
		if(String.isNotEmpty(value)){
			var parts = value.split("/");
			if(parts != null && parts.length == 3){
				var day = parseInt(parts[0], 10),
				    month = parseInt(parts[1], 10) - 1,
				    year = parseInt(parts[2], 10);

				if(year < 1900){
					return null;
				}

				var date = new Date(year, month, day, 1);
				var validValue = (date.getDate() == day && date.getMonth() == month && date.getFullYear() == year);

				// Preenche tempo:
				var hour=null, min=null;
				if(String.isNotEmpty(time)){
					var parts = time.split(":");
					if(parts != null && parts.length == 2){
						hour = parseInt(parts[0], 10);
						min = parseInt(parts[1], 10);
						date.setHours(hour);
						date.setMinutes(min);
					}
				}else{
					date.setHours(date.getHours()-1);
				}

				// Valida se foi digitado dia dentro no mês e não 31/02, por exemplo:
				if(validValue){
					if((hour == null && min == null) || (hour != null && min != null && date.getHours() == hour && date.getMinutes() == min)){
						return date;
					}
				}
			}
		}
		return null;
	};
}

if(Date.format_DDMMYYYY == null){
	Date.format_DDMMYYYY = function(date, defaultValue){
		if(date != null){
			var day = date.getDate().toPaddedString(2);
			var month = (date.getMonth()+1).toPaddedString(2);
			var year = date.getFullYear();

			return day+"/"+month+"/"+year;
		}
		return defaultValue || "";
	};
}

if(Date.joinDateTime == null){
	Date.joinDateTime = function(date, time){
		return Date.parse_DDMMYYYY(Date.format_DDMMYYYY(date), (time!=null) ? time.formatTime() : "");
	};
}

if(Date.prototype.formatTime == null){
	Date.prototype.formatTime = function(){
		return this.getHours().toPaddedString(2)+":"+this.getMinutes().toPaddedString(2);
	};
}

if(Date.prototype.toInt == null){
	Date.prototype.toInt = function(){
		var buffer = [];
		buffer.push(this.getFullYear());
		buffer.push((this.getMonth()+1).toPaddedString(2));
		buffer.push(this.getDate().toPaddedString(2));
		buffer.push(this.getHours().toPaddedString(2));
		buffer.push(this.getMinutes().toPaddedString(2));
		buffer.push(this.getSeconds().toPaddedString(2));
		buffer.push(this.getMilliseconds().toPaddedString(3));
		return buffer.join("");
	};
}

if(Date.prototype.addDay == null){
	Date.prototype.addDay = function(offset){
		var date = new Date(this.getTime());
		date.setDate(this.getDate() + offset);
		return date;
	};
}

if(Date.prototype.addMinute == null){
	Date.prototype.addMinute = function(offset){
		var date = new Date(this.getTime());
		date.setUTCMinutes(date.getUTCMinutes() + offset);
		return date;
	};
}

if(Date.prototype.runUntilWeekDay == null){
	Date.prototype.runUntilWeekDay = function(weekDay, forward, same){
		var count = 0; // Para não entrar em loop infinito:
		var date = (!same) ? new Date(this.getTime()) : this;
		while(date.getDay() != weekDay && count++ <= 7){
			date.setDate(date.getDate() + (forward ? 1 : -1));
		}
		return date;
	};
}

if(Date.getBeginEndWeek == null){
	Date.getBeginEndWeek = function(date, offsetWeek){
		if(date == null || !(date instanceof Date)) return null;
		if(!offsetWeek) offsetWeek=0;

		while(offsetWeek != 0){
			if(offsetWeek > 0){
				date = date.runUntilWeekDay(Date.SUNDAY, true).addDay(1);
				offsetWeek--;
			}else{
				date = date.runUntilWeekDay(Date.MONDAY, false).addDay(-1);
				offsetWeek++;
			}
		}

		var begin = date.runUntilWeekDay(Date.MONDAY, false);
		var end = begin.runUntilWeekDay(Date.SUNDAY, true);
		return {begin:begin, end:end};
	};
}