ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ConcurrentLinkedQueueTest.java
(Generate patch)

Comparing jsr166/src/test/tck/ConcurrentLinkedQueueTest.java (file contents):
Revision 1.1 by dl, Sun Aug 31 19:24:54 2003 UTC vs.
Revision 1.12 by jsr166, Sat Nov 21 02:07:26 2009 UTC

# Line 1 | Line 1
1   /*
2 < * Written by members of JCP JSR-166 Expert Group and released to the
3 < * public domain. Use, modify, and redistribute this code in any way
4 < * without acknowledgement. Other contributors include Andrew Wright,
5 < * Jeffrey Hayes, Pat Fischer, Mike Judd.
2 > * Written by Doug Lea with assistance from members of JCP JSR-166
3 > * Expert Group and released to the public domain, as explained at
4 > * http://creativecommons.org/licenses/publicdomain
5 > * Other contributors include Andrew Wright, Jeffrey Hayes,
6 > * Pat Fisher, Mike Judd.
7   */
8  
9   import junit.framework.*;
10   import java.util.*;
11   import java.util.concurrent.*;
12 + import java.io.*;
13  
14 < public class ConcurrentLinkedQueueTest extends TestCase {
13 <    private static final int N = 10;
14 <    private static final long SHORT_DELAY_MS = 100;
15 <    private static final long MEDIUM_DELAY_MS = 1000;
16 <    private static final long LONG_DELAY_MS = 10000;
14 > public class ConcurrentLinkedQueueTest extends JSR166TestCase {
15  
16      public static void main(String[] args) {
17 <        junit.textui.TestRunner.run (suite());  
17 >        junit.textui.TestRunner.run (suite());
18      }
19  
20      public static Test suite() {
21 <        return new TestSuite(ConcurrentLinkedQueueTest.class);
21 >        return new TestSuite(ConcurrentLinkedQueueTest.class);
22      }
23  
24      /**
25       * Create a queue of given size containing consecutive
26       * Integers 0 ... n.
27       */
28 <    private ConcurrentLinkedQueue fullQueue(int n) {
28 >    private ConcurrentLinkedQueue populatedQueue(int n) {
29          ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
30          assertTrue(q.isEmpty());
31 <        for(int i = 0; i < n; ++i)
32 <            assertTrue(q.offer(new Integer(i)));
31 >        for (int i = 0; i < n; ++i)
32 >            assertTrue(q.offer(new Integer(i)));
33          assertFalse(q.isEmpty());
34 <        assertEquals(n, q.size());
34 >        assertEquals(n, q.size());
35          return q;
36      }
37 <
38 <    public void testConstructor1(){
37 >
38 >    /**
39 >     * new queue is empty
40 >     */
41 >    public void testConstructor1() {
42          assertEquals(0, new ConcurrentLinkedQueue().size());
43      }
44  
45 +    /**
46 +     *  Initializing from null Collection throws NPE
47 +     */
48      public void testConstructor3() {
49          try {
50              ConcurrentLinkedQueue q = new ConcurrentLinkedQueue((Collection)null);
51 <            fail("Cannot make from null collection");
51 >            shouldThrow();
52          }
53          catch (NullPointerException success) {}
54      }
55  
56 <    public void testConstructor4(){
56 >    /**
57 >     * Initializing from Collection of null elements throws NPE
58 >     */
59 >    public void testConstructor4() {
60          try {
61 <            Integer[] ints = new Integer[N];
61 >            Integer[] ints = new Integer[SIZE];
62              ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(Arrays.asList(ints));
63 <            fail("Cannot make with null elements");
63 >            shouldThrow();
64          }
65          catch (NullPointerException success) {}
66      }
67  
68 <    public void testConstructor5(){
68 >    /**
69 >     * Initializing from Collection with some null elements throws NPE
70 >     */
71 >    public void testConstructor5() {
72          try {
73 <            Integer[] ints = new Integer[N];
74 <            for (int i = 0; i < N-1; ++i)
73 >            Integer[] ints = new Integer[SIZE];
74 >            for (int i = 0; i < SIZE-1; ++i)
75                  ints[i] = new Integer(i);
76              ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(Arrays.asList(ints));
77 <            fail("Cannot make with null elements");
77 >            shouldThrow();
78          }
79          catch (NullPointerException success) {}
80      }
81  
82 <    public void testConstructor6(){
82 >    /**
83 >     * Queue contains all elements of collection used to initialize
84 >     */
85 >    public void testConstructor6() {
86          try {
87 <            Integer[] ints = new Integer[N];
88 <            for (int i = 0; i < N; ++i)
87 >            Integer[] ints = new Integer[SIZE];
88 >            for (int i = 0; i < SIZE; ++i)
89                  ints[i] = new Integer(i);
90              ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(Arrays.asList(ints));
91 <            for (int i = 0; i < N; ++i)
91 >            for (int i = 0; i < SIZE; ++i)
92                  assertEquals(ints[i], q.poll());
93          }
94          finally {}
95      }
96  
97 +    /**
98 +     * isEmpty is true before add, false after
99 +     */
100      public void testEmpty() {
101          ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
102          assertTrue(q.isEmpty());
103 <        q.add(new Integer(1));
103 >        q.add(one);
104          assertFalse(q.isEmpty());
105 <        q.add(new Integer(2));
105 >        q.add(two);
106          q.remove();
107          q.remove();
108          assertTrue(q.isEmpty());
109      }
110  
111 +    /**
112 +     * size changes when elements added and removed
113 +     */
114      public void testSize() {
115 <        ConcurrentLinkedQueue q = fullQueue(N);
116 <        for (int i = 0; i < N; ++i) {
117 <            assertEquals(N-i, q.size());
115 >        ConcurrentLinkedQueue q = populatedQueue(SIZE);
116 >        for (int i = 0; i < SIZE; ++i) {
117 >            assertEquals(SIZE-i, q.size());
118              q.remove();
119          }
120 <        for (int i = 0; i < N; ++i) {
120 >        for (int i = 0; i < SIZE; ++i) {
121              assertEquals(i, q.size());
122              q.add(new Integer(i));
123          }
124      }
125  
126 <    public void testOfferNull(){
127 <        try {
126 >    /**
127 >     * offer(null) throws NPE
128 >     */
129 >    public void testOfferNull() {
130 >        try {
131              ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
132              q.offer(null);
133 <            fail("should throw NPE");
134 <        } catch (NullPointerException success) { }  
133 >            shouldThrow();
134 >        } catch (NullPointerException success) { }
135      }
136  
137 +    /**
138 +     * add(null) throws NPE
139 +     */
140 +    public void testAddNull() {
141 +        try {
142 +            ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
143 +            q.add(null);
144 +            shouldThrow();
145 +        } catch (NullPointerException success) { }
146 +    }
147 +
148 +
149 +    /**
150 +     * Offer returns true
151 +     */
152      public void testOffer() {
153          ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
154 <        assertTrue(q.offer(new Integer(0)));
155 <        assertTrue(q.offer(new Integer(1)));
154 >        assertTrue(q.offer(zero));
155 >        assertTrue(q.offer(one));
156      }
157  
158 <    public void testAdd(){
158 >    /**
159 >     * add returns true
160 >     */
161 >    public void testAdd() {
162          ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
163 <        for (int i = 0; i < N; ++i) {
163 >        for (int i = 0; i < SIZE; ++i) {
164              assertEquals(i, q.size());
165              assertTrue(q.add(new Integer(i)));
166          }
167      }
168  
169 <    public void testAddAll1(){
169 >    /**
170 >     * addAll(null) throws NPE
171 >     */
172 >    public void testAddAll1() {
173          try {
174              ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
175              q.addAll(null);
176 <            fail("Cannot add null collection");
176 >            shouldThrow();
177          }
178          catch (NullPointerException success) {}
179      }
180 <    public void testAddAll2(){
180 >
181 >    /**
182 >     * addAll(this) throws IAE
183 >     */
184 >    public void testAddAllSelf() {
185 >        try {
186 >            ConcurrentLinkedQueue q = populatedQueue(SIZE);
187 >            q.addAll(q);
188 >            shouldThrow();
189 >        }
190 >        catch (IllegalArgumentException success) {}
191 >    }
192 >
193 >    /**
194 >     * addAll of a collection with null elements throws NPE
195 >     */
196 >    public void testAddAll2() {
197          try {
198              ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
199 <            Integer[] ints = new Integer[N];
199 >            Integer[] ints = new Integer[SIZE];
200              q.addAll(Arrays.asList(ints));
201 <            fail("Cannot add null elements");
201 >            shouldThrow();
202          }
203          catch (NullPointerException success) {}
204      }
205 <    public void testAddAll3(){
205 >    /**
206 >     *  addAll of a collection with any null elements throws NPE after
207 >     * possibly adding some elements
208 >     */
209 >    public void testAddAll3() {
210          try {
211              ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
212 <            Integer[] ints = new Integer[N];
213 <            for (int i = 0; i < N-1; ++i)
212 >            Integer[] ints = new Integer[SIZE];
213 >            for (int i = 0; i < SIZE-1; ++i)
214                  ints[i] = new Integer(i);
215              q.addAll(Arrays.asList(ints));
216 <            fail("Cannot add null elements");
216 >            shouldThrow();
217          }
218          catch (NullPointerException success) {}
219      }
220  
221 <    public void testAddAll5(){
221 >    /**
222 >     * Queue contains all elements, in traversal order, of successful addAll
223 >     */
224 >    public void testAddAll5() {
225          try {
226              Integer[] empty = new Integer[0];
227 <            Integer[] ints = new Integer[N];
228 <            for (int i = 0; i < N; ++i)
227 >            Integer[] ints = new Integer[SIZE];
228 >            for (int i = 0; i < SIZE; ++i)
229                  ints[i] = new Integer(i);
230              ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
231              assertFalse(q.addAll(Arrays.asList(empty)));
232              assertTrue(q.addAll(Arrays.asList(ints)));
233 <            for (int i = 0; i < N; ++i)
233 >            for (int i = 0; i < SIZE; ++i)
234                  assertEquals(ints[i], q.poll());
235          }
236          finally {}
237      }
238  
239 <    public void testPoll(){
240 <        ConcurrentLinkedQueue q = fullQueue(N);
241 <        for (int i = 0; i < N; ++i) {
239 >    /**
240 >     * poll succeeds unless empty
241 >     */
242 >    public void testPoll() {
243 >        ConcurrentLinkedQueue q = populatedQueue(SIZE);
244 >        for (int i = 0; i < SIZE; ++i) {
245              assertEquals(i, ((Integer)q.poll()).intValue());
246          }
247 <        assertNull(q.poll());
247 >        assertNull(q.poll());
248      }
249  
250 <    public void testPeek(){
251 <        ConcurrentLinkedQueue q = fullQueue(N);
252 <        for (int i = 0; i < N; ++i) {
250 >    /**
251 >     * peek returns next element, or null if empty
252 >     */
253 >    public void testPeek() {
254 >        ConcurrentLinkedQueue q = populatedQueue(SIZE);
255 >        for (int i = 0; i < SIZE; ++i) {
256              assertEquals(i, ((Integer)q.peek()).intValue());
257              q.poll();
258              assertTrue(q.peek() == null ||
259                         i != ((Integer)q.peek()).intValue());
260          }
261 <        assertNull(q.peek());
261 >        assertNull(q.peek());
262      }
263  
264 <    public void testElement(){
265 <        ConcurrentLinkedQueue q = fullQueue(N);
266 <        for (int i = 0; i < N; ++i) {
264 >    /**
265 >     * element returns next element, or throws NSEE if empty
266 >     */
267 >    public void testElement() {
268 >        ConcurrentLinkedQueue q = populatedQueue(SIZE);
269 >        for (int i = 0; i < SIZE; ++i) {
270              assertEquals(i, ((Integer)q.element()).intValue());
271              q.poll();
272          }
273          try {
274              q.element();
275 <            fail("no such element");
275 >            shouldThrow();
276          }
277          catch (NoSuchElementException success) {}
278      }
279  
280 <    public void testRemove(){
281 <        ConcurrentLinkedQueue q = fullQueue(N);
282 <        for (int i = 0; i < N; ++i) {
280 >    /**
281 >     *  remove removes next element, or throws NSEE if empty
282 >     */
283 >    public void testRemove() {
284 >        ConcurrentLinkedQueue q = populatedQueue(SIZE);
285 >        for (int i = 0; i < SIZE; ++i) {
286              assertEquals(i, ((Integer)q.remove()).intValue());
287          }
288          try {
289              q.remove();
290 <            fail("remove should throw");
291 <        } catch (NoSuchElementException success){
292 <        }  
290 >            shouldThrow();
291 >        } catch (NoSuchElementException success) {
292 >        }
293      }
294  
295 <    public void testRemoveElement(){
296 <        ConcurrentLinkedQueue q = fullQueue(N);
297 <        for (int i = 1; i < N; i+=2) {
295 >    /**
296 >     * remove(x) removes x and returns true if present
297 >     */
298 >    public void testRemoveElement() {
299 >        ConcurrentLinkedQueue q = populatedQueue(SIZE);
300 >        for (int i = 1; i < SIZE; i+=2) {
301              assertTrue(q.remove(new Integer(i)));
302          }
303 <        for (int i = 0; i < N; i+=2) {
303 >        for (int i = 0; i < SIZE; i+=2) {
304              assertTrue(q.remove(new Integer(i)));
305              assertFalse(q.remove(new Integer(i+1)));
306          }
307 <        assert(q.isEmpty());
307 >        assertTrue(q.isEmpty());
308      }
309 <        
310 <    public void testContains(){
311 <        ConcurrentLinkedQueue q = fullQueue(N);
312 <        for (int i = 0; i < N; ++i) {
309 >
310 >    /**
311 >     * contains(x) reports true when elements added but not yet removed
312 >     */
313 >    public void testContains() {
314 >        ConcurrentLinkedQueue q = populatedQueue(SIZE);
315 >        for (int i = 0; i < SIZE; ++i) {
316              assertTrue(q.contains(new Integer(i)));
317              q.poll();
318              assertFalse(q.contains(new Integer(i)));
319          }
320      }
321  
322 <    public void testClear(){
323 <        ConcurrentLinkedQueue q = fullQueue(N);
322 >    /**
323 >     * clear removes all elements
324 >     */
325 >    public void testClear() {
326 >        ConcurrentLinkedQueue q = populatedQueue(SIZE);
327          q.clear();
328          assertTrue(q.isEmpty());
329          assertEquals(0, q.size());
330 <        q.add(new Integer(1));
330 >        q.add(one);
331          assertFalse(q.isEmpty());
332          q.clear();
333          assertTrue(q.isEmpty());
334      }
335  
336 <    public void testContainsAll(){
337 <        ConcurrentLinkedQueue q = fullQueue(N);
336 >    /**
337 >     * containsAll(c) is true when c contains a subset of elements
338 >     */
339 >    public void testContainsAll() {
340 >        ConcurrentLinkedQueue q = populatedQueue(SIZE);
341          ConcurrentLinkedQueue p = new ConcurrentLinkedQueue();
342 <        for (int i = 0; i < N; ++i) {
342 >        for (int i = 0; i < SIZE; ++i) {
343              assertTrue(q.containsAll(p));
344              assertFalse(p.containsAll(q));
345              p.add(new Integer(i));
# Line 257 | Line 347 | public class ConcurrentLinkedQueueTest e
347          assertTrue(p.containsAll(q));
348      }
349  
350 <    public void testRetainAll(){
351 <        ConcurrentLinkedQueue q = fullQueue(N);
352 <        ConcurrentLinkedQueue p = fullQueue(N);
353 <        for (int i = 0; i < N; ++i) {
350 >    /**
351 >     * retainAll(c) retains only those elements of c and reports true if change
352 >     */
353 >    public void testRetainAll() {
354 >        ConcurrentLinkedQueue q = populatedQueue(SIZE);
355 >        ConcurrentLinkedQueue p = populatedQueue(SIZE);
356 >        for (int i = 0; i < SIZE; ++i) {
357              boolean changed = q.retainAll(p);
358              if (i == 0)
359                  assertFalse(changed);
# Line 268 | Line 361 | public class ConcurrentLinkedQueueTest e
361                  assertTrue(changed);
362  
363              assertTrue(q.containsAll(p));
364 <            assertEquals(N-i, q.size());
364 >            assertEquals(SIZE-i, q.size());
365              p.remove();
366          }
367      }
368  
369 <    public void testRemoveAll(){
370 <        for (int i = 1; i < N; ++i) {
371 <            ConcurrentLinkedQueue q = fullQueue(N);
372 <            ConcurrentLinkedQueue p = fullQueue(i);
369 >    /**
370 >     * removeAll(c) removes only those elements of c and reports true if changed
371 >     */
372 >    public void testRemoveAll() {
373 >        for (int i = 1; i < SIZE; ++i) {
374 >            ConcurrentLinkedQueue q = populatedQueue(SIZE);
375 >            ConcurrentLinkedQueue p = populatedQueue(i);
376              assertTrue(q.removeAll(p));
377 <            assertEquals(N-i, q.size());
377 >            assertEquals(SIZE-i, q.size());
378              for (int j = 0; j < i; ++j) {
379                  Integer I = (Integer)(p.remove());
380                  assertFalse(q.contains(I));
# Line 286 | Line 382 | public class ConcurrentLinkedQueueTest e
382          }
383      }
384  
385 <    public void testToArray(){
386 <        ConcurrentLinkedQueue q = fullQueue(N);
387 <        Object[] o = q.toArray();
385 >    /**
386 >     * toArray contains all elements
387 >     */
388 >    public void testToArray() {
389 >        ConcurrentLinkedQueue q = populatedQueue(SIZE);
390 >        Object[] o = q.toArray();
391          Arrays.sort(o);
392 <        for(int i = 0; i < o.length; i++)
393 <            assertEquals(o[i], q.poll());
392 >        for (int i = 0; i < o.length; i++)
393 >            assertEquals(o[i], q.poll());
394      }
395  
396 <    public void testToArray2(){
397 <        ConcurrentLinkedQueue q = fullQueue(N);
398 <        Integer[] ints = new Integer[N];
399 <        ints = (Integer[])q.toArray(ints);
396 >    /**
397 >     *  toArray(a) contains all elements
398 >     */
399 >    public void testToArray2() {
400 >        ConcurrentLinkedQueue q = populatedQueue(SIZE);
401 >        Integer[] ints = new Integer[SIZE];
402 >        ints = (Integer[])q.toArray(ints);
403          Arrays.sort(ints);
404 <        for(int i = 0; i < ints.length; i++)
404 >        for (int i = 0; i < ints.length; i++)
405              assertEquals(ints[i], q.poll());
406      }
407 <    
408 <    public void testIterator(){
409 <        ConcurrentLinkedQueue q = fullQueue(N);
407 >
408 >    /**
409 >     * toArray(null) throws NPE
410 >     */
411 >    public void testToArray_BadArg() {
412 >        try {
413 >            ConcurrentLinkedQueue q = populatedQueue(SIZE);
414 >            Object o[] = q.toArray(null);
415 >            shouldThrow();
416 >        } catch (NullPointerException success) {}
417 >    }
418 >
419 >    /**
420 >     * toArray with incompatible array type throws ArrayStoreException
421 >     */
422 >    public void testToArray1_BadArg() {
423 >        try {
424 >            ConcurrentLinkedQueue q = populatedQueue(SIZE);
425 >            Object o[] = q.toArray(new String[10] );
426 >            shouldThrow();
427 >        } catch (ArrayStoreException success) {}
428 >    }
429 >
430 >    /**
431 >     *  iterator iterates through all elements
432 >     */
433 >    public void testIterator() {
434 >        ConcurrentLinkedQueue q = populatedQueue(SIZE);
435          int i = 0;
436 <        Iterator it = q.iterator();
437 <        while(it.hasNext()) {
436 >        Iterator it = q.iterator();
437 >        while (it.hasNext()) {
438              assertTrue(q.contains(it.next()));
439              ++i;
440          }
441 <        assertEquals(i, N);
441 >        assertEquals(i, SIZE);
442      }
443  
444 +    /**
445 +     * iterator ordering is FIFO
446 +     */
447      public void testIteratorOrdering() {
318
448          final ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
449 <
450 <        q.add(new Integer(1));
451 <        q.add(new Integer(2));
323 <        q.add(new Integer(3));
449 >        q.add(one);
450 >        q.add(two);
451 >        q.add(three);
452  
453          int k = 0;
454          for (Iterator it = q.iterator(); it.hasNext();) {
455              int i = ((Integer)(it.next())).intValue();
456 <            assertEquals("items should come out in order", ++k, i);
456 >            assertEquals(++k, i);
457          }
458  
459 <        assertEquals("should go through 3 elements", 3, k);
459 >        assertEquals(3, k);
460      }
461  
462 +    /**
463 +     * Modifications do not cause iterators to fail
464 +     */
465      public void testWeaklyConsistentIteration () {
335
466          final ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
467 <
468 <        q.add(new Integer(1));
469 <        q.add(new Integer(2));
340 <        q.add(new Integer(3));
467 >        q.add(one);
468 >        q.add(two);
469 >        q.add(three);
470  
471          try {
472              for (Iterator it = q.iterator(); it.hasNext();) {
# Line 346 | Line 475 | public class ConcurrentLinkedQueueTest e
475              }
476          }
477          catch (ConcurrentModificationException e) {
478 <            fail("weakly consistent iterator; should not get CME");
478 >            shouldThrow();
479          }
480  
481          assertEquals("queue should be empty again", 0, q.size());
482      }
483  
484 +    /**
485 +     * iterator.remove removes current element
486 +     */
487      public void testIteratorRemove () {
356
488          final ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
489 <
490 <        q.add(new Integer(1));
491 <        q.add(new Integer(2));
361 <        q.add(new Integer(3));
362 <
489 >        q.add(one);
490 >        q.add(two);
491 >        q.add(three);
492          Iterator it = q.iterator();
493          it.next();
494          it.remove();
366
495          it = q.iterator();
496 <        assertEquals(it.next(), new Integer(2));
497 <        assertEquals(it.next(), new Integer(3));
496 >        assertEquals(it.next(), two);
497 >        assertEquals(it.next(), three);
498          assertFalse(it.hasNext());
499      }
500  
501  
502 <    public void testToString(){
503 <        ConcurrentLinkedQueue q = fullQueue(N);
502 >    /**
503 >     * toString contains toStrings of elements
504 >     */
505 >    public void testToString() {
506 >        ConcurrentLinkedQueue q = populatedQueue(SIZE);
507          String s = q.toString();
508 <        for (int i = 0; i < N; ++i) {
508 >        for (int i = 0; i < SIZE; ++i) {
509              assertTrue(s.indexOf(String.valueOf(i)) >= 0);
510          }
511 <    }        
511 >    }
512 >
513 >    /**
514 >     * A deserialized serialized queue has same elements in same order
515 >     */
516 >    public void testSerialization() {
517 >        ConcurrentLinkedQueue q = populatedQueue(SIZE);
518 >        try {
519 >            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
520 >            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
521 >            out.writeObject(q);
522 >            out.close();
523 >
524 >            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
525 >            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
526 >            ConcurrentLinkedQueue r = (ConcurrentLinkedQueue)in.readObject();
527 >            assertEquals(q.size(), r.size());
528 >            while (!q.isEmpty())
529 >                assertEquals(q.remove(), r.remove());
530 >        } catch (Exception e) {
531 >            unexpectedException();
532 >        }
533 >    }
534  
535   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines