1   /*
2    * $Id: RegistryTest.java 124 2008-10-20 13:27:16Z arnep $
3    */
4   package net.sf.ovanttasks.ovnative.win32;
5   
6   import static org.junit.Assert.*;
7   
8   import java.io.File;
9   import java.io.FileOutputStream;
10  import java.io.InputStream;
11  import java.math.BigDecimal;
12  import java.math.BigInteger;
13  import java.util.Iterator;
14  
15  import org.junit.After;
16  import org.junit.Before;
17  import org.junit.BeforeClass;
18  import org.junit.Test;
19  
20  public class RegistryTest {
21  	// TODO test for nonexistant keys and other errors that java execptions are
22  	// thrown and no jvm crash occcurs!!
23  	static final String OV_NATIVE_TEST_SUB_KEY = "OV_Native_Tests_Delete_Me";
24  	static final String OV_NATIVE_TEST_SUB_KEY_PATH = "HKEY_CURRENT_USER\\"
25  			+ OV_NATIVE_TEST_SUB_KEY;
26  	Registry reg = null;
27  
28  	@BeforeClass
29  	public static void setUpClass() throws Exception {
30  		// System.out.println("setUpClass");
31  		OvNativeLibLoader.loadLibWithoutVersion();
32  	}
33  
34  	@Before
35  	public void setUp() throws Exception {
36  		// System.out.println("setUp");
37  		reg = new Registry(Registry.HKEY_CURRENT_USER, OV_NATIVE_TEST_SUB_KEY);
38  		try {
39  			if (reg.canOpenWith(Registry.KEY_ALL_ACCESS)) {
40  				reg.delete();
41  			}
42  		} catch (Win32Exception ex) {
43  		}
44  		reg.create();
45  	}
46  
47  	@After
48  	public void tearDown() throws Exception {
49  		// System.out.println("tearDown");
50  		if (reg != null) {
51  			try {
52  				if (reg.canOpenWith(Registry.KEY_ALL_ACCESS)) {
53  					reg.delete();
54  				}
55  			} catch (Exception e) {
56  				e.printStackTrace();
57  			}
58  
59  			reg = null;
60  		}
61  	}
62  
63  	/*
64  	 * Test method for 'net.sf.ovanttasks.ovnative.win32.Registry.create()' Test
65  	 * method for 'net.sf.ovanttasks.ovnative.win32.Registry.delete()'
66  	 */
67  	@Test
68  	public void testCreateAndDelete() {
69  		System.out.println("testCreateAndDelete");
70  		Registry reg1 = new Registry(reg.getHKey(), reg.getSubKey()
71  				+ "\\SÖFTWARE");
72  		reg1.create();
73  		assertTrue("No Key " + OV_NATIVE_TEST_SUB_KEY_PATH + "\\SÖFTWARE", reg1
74  				.exists());
75  		reg1.delete();
76  		assertFalse("Has Key " + OV_NATIVE_TEST_SUB_KEY_PATH + "\\SÖFTWARE",
77  				reg1.exists());
78  	}
79  
80  	@Test
81  	public void testCreateDeleteSubKey() {
82  		System.out.println("testCreateDeleteSubKey");
83  		assertFalse("hasSubkey", reg.hasSubKey("TestSubKey"));
84  		Registry reg1 = reg.createSubKey("TestSubKey");
85  		assertTrue("hasSubkey", reg.hasSubKey("TestSubKey"));
86  		assertEquals("TestSubKey equals", reg1, reg.openSubKey("TestSubKey"));
87  		reg.deleteSubKey("TestSubKey");
88  		assertFalse("hasSubkey", reg.hasSubKey("TestSubKey"));
89  	}
90  
91  	/*
92  	 * Test method for
93  	 * 'net.sf.ovanttasks.ovnative.win32.Registry.dumpByteArray(byte[])'
94  	 */
95  	@Test
96  	public void testDumpGetDeleteByteArray() {
97  		System.out.println("testDumpGetDeleteByteArray");
98  		byte[] values = {0, 1, 2, 3, 4, 5, 6, 7};
99  		assertFalse("Value exists", reg.hasValue("TestBytes"));
100 		reg.setValue("TestBytes", values);
101 		byte[] retValues = reg.getByteArrayValue("TestBytes");
102 		assertEquals("dumpByteArray length", values.length, retValues.length);
103 		for (int i = 0; i < values.length; i++) {
104 			assertEquals("dumpByteArray[" + i + "]", values[i], retValues[i]);
105 		}
106 		assertEquals("ByteArrayType", Registry.REG_BINARY, reg
107 				.getValueType("TestBytes"));
108 		reg.deleteValue("TestBytes");
109 		assertFalse("Value exists", reg.hasValue("TestBytes"));
110 	}
111 
112 	/*
113 	 * Test method for 'net.sf.ovanttasks.ovnative.win32.Registry.exists()'
114 	 */
115 	@Test
116 	public void testExists() {
117 		System.out.println("testExists");
118 		assertTrue("Has Key: " + OV_NATIVE_TEST_SUB_KEY_PATH, reg.exists());
119 	}
120 
121 	/*
122 	 * Test method for 'net.sf.ovanttasks.ovnative.win32.Registry.getHKey()'
123 	 */
124 	@Test
125 	public void testGetHKey() {
126 		System.out.println("testGetHKey");
127 		assertEquals("HKey", Registry.HKEY_CURRENT_USER, reg.getHKey());
128 	}
129 
130 	/*
131 	 * Test method for
132 	 * 'net.sf.ovanttasks.ovnative.win32.Registry.getHKeyName(int)'
133 	 */
134 	@Test
135 	public void testGetHKeyName() {
136 		System.out.println("testGetHKeyName");
137 		assertEquals("HKey", "HKEY_CURRENT_USER", Registry
138 				.getHKeyName(Registry.HKEY_CURRENT_USER));
139 	}
140 
141 	/*
142 	 * Test method for 'net.sf.ovanttasks.ovnative.win32.Registry.getSubKey()'
143 	 */
144 	@Test
145 	public void testCreateHasDeleteSubKey() {
146 		System.out.println("testCreateHasDeleteSubKey");
147 		assertFalse("hasSubkey", reg.hasSubKey("TestSubKey"));
148 		reg.setValue("TestSubKey", "TestSubKey");
149 		Registry reg1 = reg.createSubKey("TestSubKey");
150 		assertTrue("hasSubkey", reg.hasSubKey("TestSubKey"));
151 		assertFalse("hasSubkey", reg.hasSubKey("TestSubKey1"));
152 		reg1.delete();
153 		assertFalse("hasSubkey", reg.hasSubKey("TestSubKey"));
154 	}
155 
156 	/*
157 	 * Test method for
158 	 * 'net.sf.ovanttasks.ovnative.win32.Registry.getBigDecimalValue(String)'
159 	 */
160 	@Test
161 	public void testSetGetDeleteBigDecimalValue() {
162 		System.out.println("testSetGetDeleteBigDecimalValue");
163 		assertFalse("Value exists", reg.hasValue("TestBigDecimal"));
164 		reg.setValue("TestBigDecimal", new BigDecimal(42.0));
165 		assertEquals("setBigDecimalValue", new BigDecimal(42.0), reg
166 				.getBigDecimalValue("TestBigDecimal"));
167 		assertEquals("BigDecimalValueType", Registry.REG_SZ, reg
168 				.getValueType("TestBigDecimal"));
169 		reg.deleteValue("TestBigDecimal");
170 		assertFalse("Value exists", reg.hasValue("TestBigDecimal"));
171 	}
172 
173 	/*
174 	 * Test method for
175 	 * 'net.sf.ovanttasks.ovnative.win32.Registry.getBigIntegerValue(String)'
176 	 */
177 	@Test
178 	public void testSetGetDeleteBigIntegerValue() {
179 		System.out.println("testSetGetDeleteBigIntegerValue");
180 		assertFalse("Value exists", reg.hasValue("TestBigInteger"));
181 		reg.setValue("TestBigInteger", new BigInteger("42"));
182 		assertEquals("setBigIntegerValue", new BigInteger("42"), reg
183 				.getBigIntegerValue("TestBigInteger"));
184 		assertEquals("BigDecimalValueType", Registry.REG_SZ, reg
185 				.getValueType("TestBigInteger"));
186 		reg.deleteValue("TestBigInteger");
187 		assertFalse("Value exists", reg.hasValue("TestBigInteger"));
188 	}
189 
190 	/*
191 	 * Test method for
192 	 * 'net.sf.ovanttasks.ovnative.win32.Registry.getBooleanValue(String)'
193 	 */
194 	@Test
195 	public void testSetGetDeleteBooleanValue() {
196 		System.out.println("testSetGetDeleteBooleanValue");
197 		assertFalse("Value exists", reg.hasValue("TestBoolean"));
198 		reg.setValue("TestBoolean", true);
199 		assertEquals("setBoolValue", true, reg.getBooleanValue("TestBoolean"));
200 		assertEquals("BoolValueType", Registry.REG_DWORD, reg
201 				.getValueType("TestBoolean"));
202 		reg.deleteValue("TestBoolean");
203 		assertFalse("Value exists", reg.hasValue("TestBoolean"));
204 	}
205 
206 	/*
207 	 * Test method for
208 	 * 'net.sf.ovanttasks.ovnative.win32.Registry.getByteValue(String)'
209 	 */
210 	@Test
211 	public void testSetGetDeleteByteValue() {
212 		System.out.println("testSetGetDeleteByteValue");
213 		assertFalse("Value exists", reg.hasValue("TestByte"));
214 		reg.setValue("TestByte", (byte) 1);
215 		assertEquals("setByteValue", (byte) 1, reg.getByteValue("TestByte"));
216 		assertEquals("ByteValueType", Registry.REG_DWORD, reg
217 				.getValueType("TestByte"));
218 		reg.deleteValue("TestByte");
219 		assertFalse("Value exists", reg.hasValue("TestByte"));
220 	}
221 
222 	/*
223 	 * Test method for
224 	 * 'net.sf.ovanttasks.ovnative.win32.Registry.getDoubleValue(String)'
225 	 */
226 	@Test
227 	public void testSetGetDeleteDoubleValue() {
228 		System.out.println("testSetGetDeleteDoubleValue");
229 		assertFalse("Value exists", reg.hasValue("TestDouble"));
230 		reg.setValue("TestDouble", (double) 42.0);
231 		assertEquals("setDoubleValue", (double) 42.0, reg
232 				.getDoubleValue("TestDouble"), Double.MIN_VALUE);
233 		assertEquals("DoubleValueType", Registry.REG_SZ, reg
234 				.getValueType("TestDouble"));
235 		reg.deleteValue("TestDouble");
236 		assertFalse("Value exists", reg.hasValue("TestDouble"));
237 	}
238 
239 	/*
240 	 * Test method for
241 	 * 'net.sf.ovanttasks.ovnative.win32.Registry.getFloatValue(String)'
242 	 */
243 	@Test
244 	public void testSetGetDeleteFloatValue() {
245 		System.out.println("testSetGetDeleteFloatValue");
246 		assertFalse("Value exists", reg.hasValue("TestFloat"));
247 		reg.setValue("TestFloat", (float) 42.0);
248 		assertEquals("setFloatValue", (float) 42.0, reg
249 				.getFloatValue("TestFloat"), Float.MIN_VALUE);
250 		assertEquals("FloatValueType", Registry.REG_SZ, reg
251 				.getValueType("TestFloat"));
252 		reg.deleteValue("TestFloat");
253 		assertFalse("Value exists", reg.hasValue("TestFloat"));
254 	}
255 
256 	/*
257 	 * Test method for
258 	 * 'net.sf.ovanttasks.ovnative.win32.Registry.getIntValue(String)'
259 	 */
260 	@Test
261 	public void testSetGetDeleteIntValue() {
262 		System.out.println("testSetGetDeleteIntValue");
263 		assertFalse("Value exists", reg.hasValue("TestInt"));
264 		reg.setValue("TestInt", (int) 42);
265 		assertEquals("setIntValue", (int) 42, reg.getIntValue("TestInt"));
266 		assertEquals("IntValueType", Registry.REG_DWORD, reg
267 				.getValueType("TestInt"));
268 		reg.deleteValue("TestInt");
269 		assertFalse("Value exists", reg.hasValue("TestInt"));
270 	}
271 
272 	/*
273 	 * Test method for
274 	 * 'net.sf.ovanttasks.ovnative.win32.Registry.getLongValue(String)'
275 	 */
276 	@Test
277 	public void testSetGetDeleteLongValue() {
278 		System.out.println("testSetGetDeleteLongValue");
279 		assertFalse("Value exists", reg.hasValue("TestLong"));
280 		reg.setValue("TestLong", (long) 42);
281 		assertEquals("setLongValue", (long) 42, reg.getLongValue("TestLong"));
282 		assertEquals("longValueType", Registry.REG_SZ, reg
283 				.getValueType("TestLong"));
284 		reg.deleteValue("TestLong");
285 		assertFalse("Value exists", reg.hasValue("TestLong"));
286 	}
287 
288 	/*
289 	 * Test method for
290 	 * 'net.sf.ovanttasks.ovnative.win32.Registry.getShortValue(String)'
291 	 */
292 	@Test
293 	public void testSetGetDeleteShortValue() {
294 		System.out.println("testSetGetDeleteShortValue");
295 		assertFalse("Value exists", reg.hasValue("TestShort"));
296 		reg.setValue("TestShort", (short) 1);
297 		assertEquals("setShortValue", (short) 1, reg.getShortValue("TestShort"));
298 		assertEquals("ShortValueType", Registry.REG_DWORD, reg
299 				.getValueType("TestShort"));
300 		reg.deleteValue("TestShort");
301 		assertFalse("Value exists", reg.hasValue("TestShort"));
302 	}
303 
304 	/*
305 	 * Test method for
306 	 * 'net.sf.ovanttasks.ovnative.win32.Registry.setValue(String, String)'
307 	 */
308 	@Test
309 	public void testSetGetDeleteStringValue() {
310 		System.out.println("testSetGetDeleteStringValue");
311 		assertFalse("Value exists", reg.hasValue("TestString"));
312 		reg.setValue("TestString", "TestStringValue");
313 		assertEquals("setStringValue", "TestStringValue", reg
314 				.getStringValue("TestString"));
315 		assertEquals("StringValueType", Registry.REG_SZ, reg
316 				.getValueType("TestString"));
317 		reg.deleteValue("TestString");
318 		assertFalse("Value exists", reg.hasValue("TestString"));
319 	}
320 
321 	/*
322 	 * Test method for
323 	 * 'net.sf.ovanttasks.ovnative.win32.Registry.setValue(String, String)'
324 	 */
325 	@Test
326 	public void testSetGetDeleteStringValueWithLentht0() {
327 		System.out.println("testSetGetDeleteStringValueWithLentht0");
328 		assertFalse("Value exists", reg.hasValue("TestString"));
329 		reg.setValue("TestString", "");
330 		assertEquals("setStringValue", "", reg.getStringValue("TestString"));
331 		assertEquals("StringValueType", Registry.REG_SZ, reg
332 				.getValueType("TestString"));
333 		reg.deleteValue("TestString");
334 		assertFalse("Value exists", reg.hasValue("TestString"));
335 	}
336 
337 	/*
338 	 * Test method for
339 	 * 'net.sf.ovanttasks.ovnative.win32.Registry.setExpandable(String, String)'
340 	 */
341 	@Test
342 	public void testSetGetDeleteExpandableStringValue() {
343 		System.out.println("testSetGetDeleteExpandableStringValue");
344 		assertFalse("Value exists", reg.hasValue("TestString"));
345 		reg.setExpandableString("TestString", "TestString%TEMP%");
346 		assertEquals("StringValueType", Registry.REG_EXPAND_SZ, reg
347 				.getValueType("TestString"));
348 		assertEquals("StringValue", "TestString"
349 				+ System.getProperty("java.io.tmpdir"), reg
350 				.getExpandableString("TestString", true)
351 				+ "\\");
352 		assertEquals("StringValue", "TestString%TEMP%", reg
353 				.getExpandableString("TestString", false));
354 		reg.deleteValue("TestString");
355 		assertFalse("Value exists", reg.hasValue("TestString"));
356 	}
357 
358 	/*
359 	 * Test method for
360 	 * 'net.sf.ovanttasks.ovnative.win32.Registry.setExpandable(String, String)'
361 	 */
362 	@Test
363 	public void testSetGetDeleteMultiStringValue() {
364 		System.out.println("testSetGetDeleteMultiStringValue");
365 		// TODO implement
366 		assertFalse("Value exists", reg.hasValue("TestMultiString"));
367 		String[] values = new String[]{"MultiString1", "MultiSting2"};
368 		reg.setValue("TestMultiString", values);
369 		assertTrue("Value exists", reg.hasValue("TestMultiString"));
370 		assertEquals("StringValueType", Registry.REG_MULTI_SZ, reg
371 				.getValueType("TestMultiString"));
372 		String[] readed = reg.getMultiStringValue("TestMultiString");
373 		assertEquals(2, readed.length);
374 		assertEquals("StringValue1", values[0], readed[0]);
375 		assertEquals("StringValue1", values[1], readed[1]);
376 		reg.deleteValue("TestMultiString");
377 		assertFalse("Value exists", reg.hasValue("TestMultiString"));
378 	}
379 
380 	/*
381 	 * Test method for 'net.sf.ovanttasks.ovnative.win32.Registry.subKeyNames()'
382 	 */
383 	@Test
384 	public void testSubKey() {
385 		System.out.println("testSubKey");
386 		// Setup
387 		String[] subKeyNames = reg.subKeyNames();
388 		Iterator<Registry> iterSubKeys = reg.subKeys();
389 		assertEquals("SubKeyNames", 0, subKeyNames.length); // check really
390 		// empty
391 		assertFalse("SubKeys", iterSubKeys.hasNext()); // check really empty
392 		Registry[] regs = new Registry[]{reg.createSubKey("TestSubKey0"),
393 				reg.createSubKey("TestSubKey1"),
394 				reg.createSubKey("TestSubKey2")};
395 
396 		// Test
397 		subKeyNames = reg.subKeyNames();
398 		iterSubKeys = reg.subKeys();
399 		assertEquals("subKeyNames.length", 3, subKeyNames.length);
400 		for (int i = 0; i < subKeyNames.length; i++) {
401 			assertEquals("SubKeyNames TestSubKey" + i, "TestSubKey" + i,
402 					subKeyNames[i]);
403 			assertTrue("SubKeys", iterSubKeys.hasNext());
404 			assertEquals("SubKeys TestSubKey" + i, regs[i], iterSubKeys.next());
405 		}
406 		assertFalse("SubKeys", iterSubKeys.hasNext());
407 	}
408 
409 	/*
410 	 * Test method for 'net.sf.ovanttasks.ovnative.win32.Registry.subKeyNames()'
411 	 */
412 	@Test
413 	public void testSubKey_0000() {
414 		System.out.println("testSubKey_0000");
415 		// Setup
416 		String[] subKeyNames = reg.subKeyNames();
417 		assertEquals("SubKeyNames", 0, subKeyNames.length); // check really
418 		// empty
419 		Registry[] regs = new Registry[]{reg.createSubKey("0000")};
420 
421 		// Test
422 		subKeyNames = reg.subKeyNames();
423 		assertEquals("subKeyNames.length", 1, subKeyNames.length);
424 		assertEquals("SubKeyName", "0000", subKeyNames[0]);
425 	}
426 
427 	/*
428 	 * Test method for 'net.sf.ovanttasks.ovnative.win32.Registry.toString()'
429 	 */
430 	@Test
431 	public void testToString() {
432 		System.out.println("testToString");
433 		assertEquals("toString", OV_NATIVE_TEST_SUB_KEY_PATH, reg.toString());
434 	}
435 
436 	/*
437 	 * Test method for 'net.sf.ovanttasks.ovnative.win32.Registry.valueNames()'
438 	 */
439 	@Test
440 	public void testValueNames() {
441 		System.out.println("testValueNames");
442 		// Setup
443 		String[] valueNames = reg.valueNames();
444 		assertEquals("ValueNames", 0, valueNames.length); // check really
445 		// empty
446 		reg.setValue("TestValue0", "TestValue0");
447 		reg.setValue("TestValue1", "TestValue1");
448 		reg.setValue("TestValue2", "TestValue2");
449 		// Test
450 		valueNames = reg.valueNames();
451 		assertEquals(3, valueNames.length);
452 		for (int i = 0; i < valueNames.length; i++) {
453 			assertEquals("ValueName TestValue" + i, "TestValue" + i,
454 					valueNames[i]);
455 		}
456 	}
457 
458 	@Test
459 	public void testWithRegedit_5() throws Exception {
460 		System.out.println("testWithRegedit_5");
461 		reg.delete();
462 		assertFalse("hasSubkey", reg.hasSubKey("TestRegEdit_5SubKey"));
463 
464 		File tmpFile = File.createTempFile("RegeditTest", ".reg");
465 		tmpFile.deleteOnExit();
466 		InputStream is = RegistryTest.class
467 				.getResourceAsStream("TestDataFixture_For_TestRegEdit_5.reg");
468 		FileOutputStream os = new FileOutputStream(tmpFile);
469 		int data;
470 		while ((data = is.read()) != -1) {
471 			os.write(data);
472 		}
473 		is.close();
474 		os.close();
475 
476 		Process p = Runtime.getRuntime().exec(
477 				new String[]{"regedit", "/s", tmpFile.getAbsolutePath()});
478 		p.waitFor();
479 		assertEquals("Importing registry with regedit", 0, p.exitValue());
480 		assertTrue("hasSubkey", reg.hasSubKey("TestRegEdit_5SubKey"));
481 		Registry reg1 = reg.openSubKey("TestRegEdit_5SubKey");
482 		assertEquals("ExpandableString%PATH%", reg1.getExpandableString(
483 				"ExpandableString", false));
484 		assertEquals(new BigDecimal(1234567890.0987654321), reg1
485 				.getBigDecimalValue("BigDecimal"));
486 		assertEquals(new BigInteger("1234567890"), reg1
487 				.getBigIntegerValue("BigInteger"));
488 		assertEquals(true, reg1.getBooleanValue("Boolean"));
489 		byte[] byteArray = reg1.getByteArrayValue("ByteArray");
490 		assertEquals((byte) 1, byteArray[0]);
491 		assertEquals((byte) 2, byteArray[1]);
492 		assertEquals((byte) 3, byteArray[2]);
493 		assertEquals((byte) 4, byteArray[3]);
494 		assertEquals((byte) 5, byteArray[4]);
495 		assertEquals((byte) 6, byteArray[5]);
496 		assertEquals((byte) 7, byteArray[6]);
497 		assertEquals((byte) 8, byteArray[7]);
498 		assertEquals((byte) 9, byteArray[8]);
499 		assertEquals((byte) 128, reg1.getByteValue("Byte"));
500 		assertEquals((short) 32767, reg1.getShortValue("Short"));
501 		assertEquals(2147483647, reg1.getIntValue("Integer"));
502 		assertEquals(2147483647L, reg1.getLongValue("Long"));
503 		assertEquals((float) 1.0, reg1.getFloatValue("Float"), Float.MIN_NORMAL);
504 		assertEquals(-1.0987654321, reg1.getDoubleValue("Double"),
505 				Double.MIN_NORMAL);
506 		assertEquals("Orangevolt Ant Tasks", reg1.getStringValue("String"));
507 		String[] multiString = reg1.getMultiStringValue("MultiString");
508 		assertEquals(2, multiString.length);
509 		assertEquals("Phoenix - AwardBIOS v6.00PG", multiString[0]);
510 		assertEquals("Phoenix - AwardBIOS v6.00PG", multiString[1]);
511 		assertEquals("", reg1.getStringValue("EmptyString"));
512 		String[] subKeys = reg1.subKeyNames();
513 		assertEquals(1, subKeys.length);
514 		assertEquals("0000", subKeys[0]);
515 	}
516 
517 	/*
518 	 * Test method for
519 	 * 'net.sf.ovanttasks.ovnative.win32.Registry.getBooleanValue(String)'
520 	 */
521 	@Test
522 	public void testHasValue() {
523 		System.out.println("testHasValue");
524 		assertFalse("Value exists", reg.hasValue("TestBoolean"));
525 		reg.setValue("TestBoolean", true);
526 		assertEquals("hasValue", true, reg.hasValue("TestBoolean"));
527 
528 		reg.deleteValue("TestBoolean");
529 		assertFalse("Value exists", reg.hasValue("TestBoolean"));
530 	}
531 
532 	@Test
533 	public void testValueNames_1() {
534 		System.out.println("testValueNames_1");
535 		Registry reg = new Registry(Registry.HKEY_CURRENT_USER,
536 				"Software\\Microsoft\\Windows\\ShellNoRoam\\MUICache");
537 		// Any way to test if this is correct??
538 		// assertEquals(14, reg.valueNames().length);
539 		// or just check if ther is any data?
540 		assertTrue(reg.valueNames().length > 0);
541 
542 	}
543 }