1 16 package org.joda.time; 17 18 import java.io.ByteArrayInputStream ; 19 import java.io.ByteArrayOutputStream ; 20 import java.io.ObjectInputStream ; 21 import java.io.ObjectOutputStream ; 22 import java.util.Locale ; 23 import java.util.TimeZone ; 24 25 import junit.framework.TestCase; 26 import junit.framework.TestSuite; 27 28 import org.joda.time.base.AbstractInterval; 29 import org.joda.time.chrono.CopticChronology; 30 import org.joda.time.chrono.GJChronology; 31 import org.joda.time.chrono.ISOChronology; 32 33 38 public class TestMutableInterval_Basics extends TestCase { 39 42 private static final DateTimeZone PARIS = DateTimeZone.forID("Europe/Paris"); 43 private static final DateTimeZone LONDON = DateTimeZone.forID("Europe/London"); 44 private static final Chronology COPTIC_PARIS = CopticChronology.getInstance(PARIS); 45 46 long y2002days = 365 + 365 + 366 + 365 + 365 + 365 + 366 + 365 + 365 + 365 + 47 366 + 365 + 365 + 365 + 366 + 365 + 365 + 365 + 366 + 365 + 48 365 + 365 + 366 + 365 + 365 + 365 + 366 + 365 + 365 + 365 + 49 366 + 365; 50 long y2003days = 365 + 365 + 366 + 365 + 365 + 365 + 366 + 365 + 365 + 365 + 51 366 + 365 + 365 + 365 + 366 + 365 + 365 + 365 + 366 + 365 + 52 365 + 365 + 366 + 365 + 365 + 365 + 366 + 365 + 365 + 365 + 53 366 + 365 + 365; 54 55 private long TEST_TIME_NOW = 57 (y2002days + 31L + 28L + 31L + 30L + 31L + 9L -1L) * DateTimeConstants.MILLIS_PER_DAY; 58 59 private long TEST_TIME1 = 61 (y2002days + 31L + 28L + 31L + 5L -1L) * DateTimeConstants.MILLIS_PER_DAY 62 + 12L * DateTimeConstants.MILLIS_PER_HOUR 63 + 24L * DateTimeConstants.MILLIS_PER_MINUTE; 64 65 private long TEST_TIME2 = 67 (y2003days + 31L + 28L + 31L + 30L + 6L -1L) * DateTimeConstants.MILLIS_PER_DAY 68 + 14L * DateTimeConstants.MILLIS_PER_HOUR 69 + 28L * DateTimeConstants.MILLIS_PER_MINUTE; 70 71 private DateTimeZone originalDateTimeZone = null; 72 private TimeZone originalTimeZone = null; 73 private Locale originalLocale = null; 74 75 public static void main(String [] args) { 76 junit.textui.TestRunner.run(suite()); 77 } 78 79 public static TestSuite suite() { 80 return new TestSuite(TestMutableInterval_Basics.class); 81 } 82 83 public TestMutableInterval_Basics(String name) { 84 super(name); 85 } 86 87 protected void setUp() throws Exception { 88 DateTimeUtils.setCurrentMillisFixed(TEST_TIME_NOW); 89 originalDateTimeZone = DateTimeZone.getDefault(); 90 originalTimeZone = TimeZone.getDefault(); 91 originalLocale = Locale.getDefault(); 92 DateTimeZone.setDefault(LONDON); 93 TimeZone.setDefault(TimeZone.getTimeZone("Europe/London")); 94 Locale.setDefault(Locale.UK); 95 } 96 97 protected void tearDown() throws Exception { 98 DateTimeUtils.setCurrentMillisSystem(); 99 DateTimeZone.setDefault(originalDateTimeZone); 100 TimeZone.setDefault(originalTimeZone); 101 Locale.setDefault(originalLocale); 102 originalDateTimeZone = null; 103 originalTimeZone = null; 104 originalLocale = null; 105 } 106 107 public void testTest() { 109 assertEquals("2002-06-09T00:00:00.000Z", new Instant(TEST_TIME_NOW).toString()); 110 assertEquals("2002-04-05T12:24:00.000Z", new Instant(TEST_TIME1).toString()); 111 assertEquals("2003-05-06T14:28:00.000Z", new Instant(TEST_TIME2).toString()); 112 } 113 114 public void testGetMillis() { 116 MutableInterval test = new MutableInterval(TEST_TIME1, TEST_TIME2); 117 assertEquals(TEST_TIME1, test.getStartMillis()); 118 assertEquals(TEST_TIME1, test.getStart().getMillis()); 119 assertEquals(TEST_TIME2, test.getEndMillis()); 120 assertEquals(TEST_TIME2, test.getEnd().getMillis()); 121 assertEquals(TEST_TIME2 - TEST_TIME1, test.toDurationMillis()); 122 assertEquals(TEST_TIME2 - TEST_TIME1, test.toDuration().getMillis()); 123 } 124 125 public void testGetDuration1() { 126 MutableInterval test = new MutableInterval(TEST_TIME1, TEST_TIME2); 127 assertEquals(TEST_TIME2 - TEST_TIME1, test.toDurationMillis()); 128 assertEquals(TEST_TIME2 - TEST_TIME1, test.toDuration().getMillis()); 129 } 130 131 public void testGetDuration2() { 132 MutableInterval test = new MutableInterval(TEST_TIME1, TEST_TIME1); 133 assertSame(Duration.ZERO, test.toDuration()); 134 } 135 136 public void testEqualsHashCode() { 137 MutableInterval test1 = new MutableInterval(TEST_TIME1, TEST_TIME2); 138 MutableInterval test2 = new MutableInterval(TEST_TIME1, TEST_TIME2); 139 assertEquals(true, test1.equals(test2)); 140 assertEquals(true, test2.equals(test1)); 141 assertEquals(true, test1.equals(test1)); 142 assertEquals(true, test2.equals(test2)); 143 assertEquals(true, test1.hashCode() == test2.hashCode()); 144 assertEquals(true, test1.hashCode() == test1.hashCode()); 145 assertEquals(true, test2.hashCode() == test2.hashCode()); 146 147 MutableInterval test3 = new MutableInterval(TEST_TIME_NOW, TEST_TIME2); 148 assertEquals(false, test1.equals(test3)); 149 assertEquals(false, test2.equals(test3)); 150 assertEquals(false, test3.equals(test1)); 151 assertEquals(false, test3.equals(test2)); 152 assertEquals(false, test1.hashCode() == test3.hashCode()); 153 assertEquals(false, test2.hashCode() == test3.hashCode()); 154 155 MutableInterval test4 = new MutableInterval(TEST_TIME1, TEST_TIME2, GJChronology.getInstance()); 156 assertEquals(true, test4.equals(test4)); 157 assertEquals(false, test1.equals(test4)); 158 assertEquals(false, test2.equals(test4)); 159 assertEquals(false, test4.equals(test1)); 160 assertEquals(false, test4.equals(test2)); 161 assertEquals(false, test1.hashCode() == test4.hashCode()); 162 assertEquals(false, test2.hashCode() == test4.hashCode()); 163 164 MutableInterval test5 = new MutableInterval(TEST_TIME1, TEST_TIME2); 165 assertEquals(true, test1.equals(test5)); 166 assertEquals(true, test2.equals(test5)); 167 assertEquals(false, test3.equals(test5)); 168 assertEquals(true, test5.equals(test1)); 169 assertEquals(true, test5.equals(test2)); 170 assertEquals(false, test5.equals(test3)); 171 assertEquals(true, test1.hashCode() == test5.hashCode()); 172 assertEquals(true, test2.hashCode() == test5.hashCode()); 173 assertEquals(false, test3.hashCode() == test5.hashCode()); 174 175 assertEquals(false, test1.equals("Hello")); 176 assertEquals(true, test1.equals(new MockInterval())); 177 assertEquals(false, test1.equals(new DateTime(TEST_TIME1))); 178 } 179 180 class MockInterval extends AbstractInterval { 181 public MockInterval() { 182 super(); 183 } 184 public Chronology getChronology() { 185 return ISOChronology.getInstance(); 186 } 187 public long getStartMillis() { 188 return TEST_TIME1; 189 } 190 public long getEndMillis() { 191 return TEST_TIME2; 192 } 193 } 194 195 public void testContains_long() { 197 MutableInterval test = new MutableInterval(TEST_TIME1, TEST_TIME2); 198 assertEquals(true, test.contains(TEST_TIME1)); 199 assertEquals(false, test.contains(TEST_TIME1 - 1)); 200 assertEquals(true, test.contains(TEST_TIME1 + (TEST_TIME2 - TEST_TIME1) / 2)); 201 assertEquals(false, test.contains(TEST_TIME2)); 202 assertEquals(true, test.contains(TEST_TIME2 - 1)); 203 } 204 205 public void testContainsNow() { 206 MutableInterval test = new MutableInterval(TEST_TIME1, TEST_TIME2); 207 208 DateTimeUtils.setCurrentMillisFixed(TEST_TIME1); 209 assertEquals(true, test.containsNow()); 210 DateTimeUtils.setCurrentMillisFixed(TEST_TIME1 - 1); 211 assertEquals(false, test.containsNow()); 212 DateTimeUtils.setCurrentMillisFixed(TEST_TIME1 + (TEST_TIME2 - TEST_TIME1) / 2); 213 assertEquals(true, test.containsNow()); 214 DateTimeUtils.setCurrentMillisFixed(TEST_TIME2); 215 assertEquals(false, test.containsNow()); 216 DateTimeUtils.setCurrentMillisFixed(TEST_TIME2 - 1); 217 assertEquals(true, test.containsNow()); 218 } 219 220 public void testContains_RI() { 221 MutableInterval test = new MutableInterval(TEST_TIME1, TEST_TIME2); 222 assertEquals(true, test.contains(new Instant(TEST_TIME1))); 223 assertEquals(false, test.contains(new Instant(TEST_TIME1 - 1))); 224 assertEquals(true, test.contains(new Instant(TEST_TIME1 + (TEST_TIME2 - TEST_TIME1) / 2))); 225 assertEquals(false, test.contains(new Instant(TEST_TIME2))); 226 assertEquals(true, test.contains(new Instant(TEST_TIME2 - 1))); 227 assertEquals(true, test.contains((ReadableInstant) null)); 228 } 229 230 public void testContains_RInterval() { 232 MutableInterval test = new MutableInterval(TEST_TIME1, TEST_TIME2); 233 234 assertEquals(true, test.contains(new Interval(TEST_TIME1, TEST_TIME1))); 235 assertEquals(false, test.contains(new Interval(TEST_TIME1 - 1, TEST_TIME1))); 236 237 assertEquals(true, test.contains(new Interval(TEST_TIME1, TEST_TIME1 + 1))); 238 assertEquals(false, test.contains(new Interval(TEST_TIME1 - 1, TEST_TIME1 + 1))); 239 assertEquals(true, test.contains(new Interval(TEST_TIME1 + 1, TEST_TIME1 + 1))); 240 241 assertEquals(true, test.contains(new Interval(TEST_TIME1, TEST_TIME2))); 242 assertEquals(false, test.contains(new Interval(TEST_TIME1 - 1, TEST_TIME2))); 243 assertEquals(true, test.contains(new Interval(TEST_TIME1 + (TEST_TIME2 - TEST_TIME1) / 2, TEST_TIME2))); 244 assertEquals(false, test.contains(new Interval(TEST_TIME2, TEST_TIME2))); 245 assertEquals(true, test.contains(new Interval(TEST_TIME2 - 1, TEST_TIME2))); 246 247 assertEquals(true, test.contains(new Interval(TEST_TIME1, TEST_TIME2 - 1))); 248 assertEquals(false, test.contains(new Interval(TEST_TIME1 - 1, TEST_TIME2 - 1))); 249 assertEquals(true, test.contains(new Interval(TEST_TIME1 + (TEST_TIME2 - TEST_TIME1) / 2, TEST_TIME2 - 1))); 250 assertEquals(true, test.contains(new Interval(TEST_TIME2 - 1, TEST_TIME2 - 1))); 251 assertEquals(true, test.contains(new Interval(TEST_TIME2 - 2, TEST_TIME2 - 1))); 252 253 assertEquals(false, test.contains(new Interval(TEST_TIME1, TEST_TIME2 + 1))); 254 assertEquals(false, test.contains(new Interval(TEST_TIME1 - 1, TEST_TIME2 + 1))); 255 assertEquals(false, test.contains(new Interval(TEST_TIME1 + (TEST_TIME2 - TEST_TIME1) / 2, TEST_TIME2 + 1))); 256 assertEquals(false, test.contains(new Interval(TEST_TIME2, TEST_TIME2 + 1))); 257 assertEquals(false, test.contains(new Interval(TEST_TIME2 - 1, TEST_TIME2 + 1))); 258 assertEquals(false, test.contains(new Interval(TEST_TIME1 - 2, TEST_TIME1 - 1))); 259 260 assertEquals(true, test.contains((ReadableInterval) null)); 261 } 262 263 public void testOverlaps_RInterval() { 264 MutableInterval test = new MutableInterval(TEST_TIME1, TEST_TIME2); 265 266 assertEquals(false, test.overlaps(new Interval(TEST_TIME1, TEST_TIME1))); 267 assertEquals(false, test.overlaps(new Interval(TEST_TIME1 - 1, TEST_TIME1))); 268 269 assertEquals(true, test.overlaps(new Interval(TEST_TIME1, TEST_TIME1 + 1))); 270 assertEquals(true, test.overlaps(new Interval(TEST_TIME1 - 1, TEST_TIME1 + 1))); 271 assertEquals(true, test.overlaps(new Interval(TEST_TIME1 + 1, TEST_TIME1 + 1))); 272 273 assertEquals(true, test.overlaps(new Interval(TEST_TIME1, TEST_TIME2))); 274 assertEquals(true, test.overlaps(new Interval(TEST_TIME1 - 1, TEST_TIME2))); 275 assertEquals(true, test.overlaps(new Interval(TEST_TIME1 + (TEST_TIME2 - TEST_TIME1) / 2, TEST_TIME2))); 276 assertEquals(false, test.overlaps(new Interval(TEST_TIME2, TEST_TIME2))); 277 assertEquals(true, test.overlaps(new Interval(TEST_TIME2 - 1, TEST_TIME2))); 278 279 assertEquals(true, test.overlaps(new Interval(TEST_TIME1, TEST_TIME2 + 1))); 280 assertEquals(true, test.overlaps(new Interval(TEST_TIME1 - 1, TEST_TIME2 + 1))); 281 assertEquals(true, test.overlaps(new Interval(TEST_TIME1 + (TEST_TIME2 - TEST_TIME1) / 2, TEST_TIME2 + 1))); 282 assertEquals(false, test.overlaps(new Interval(TEST_TIME2, TEST_TIME2 + 1))); 283 assertEquals(true, test.overlaps(new Interval(TEST_TIME2 - 1, TEST_TIME2 + 1))); 284 285 assertEquals(false, test.overlaps(new Interval(TEST_TIME1 - 1, TEST_TIME1 - 1))); 286 assertEquals(false, test.overlaps(new Interval(TEST_TIME1 - 1, TEST_TIME1))); 287 assertEquals(true, test.overlaps(new Interval(TEST_TIME1 - 1, TEST_TIME1 + 1))); 288 289 assertEquals(true, test.overlaps((ReadableInterval) null)); 290 291 MutableInterval empty = new MutableInterval(TEST_TIME1, TEST_TIME1); 292 assertEquals(false, empty.overlaps(empty)); 293 assertEquals(false, empty.overlaps(test)); 294 assertEquals(false, test.overlaps(empty)); 295 } 296 297 public void testIsBefore_long() { 299 MutableInterval test = new MutableInterval(TEST_TIME1, TEST_TIME2); 300 301 assertEquals(false, test.isBefore(TEST_TIME1 - 1)); 302 assertEquals(false, test.isBefore(TEST_TIME1)); 303 assertEquals(false, test.isBefore(TEST_TIME1 + 1)); 304 305 assertEquals(false, test.isBefore(TEST_TIME2 - 1)); 306 assertEquals(true, test.isBefore(TEST_TIME2)); 307 assertEquals(true, test.isBefore(TEST_TIME2 + 1)); 308 } 309 310 public void testIsBeforeNow() { 311 MutableInterval test = new MutableInterval(TEST_TIME1, TEST_TIME2); 312 313 DateTimeUtils.setCurrentMillisFixed(TEST_TIME2 - 1); 314 assertEquals(false, test.isBeforeNow()); 315 DateTimeUtils.setCurrentMillisFixed(TEST_TIME2); 316 assertEquals(true, test.isBeforeNow()); 317 DateTimeUtils.setCurrentMillisFixed(TEST_TIME2 + 1); 318 assertEquals(true, test.isBeforeNow()); 319 } 320 321 public void testIsBefore_RI() { 322 MutableInterval test = new MutableInterval(TEST_TIME1, TEST_TIME2); 323 324 assertEquals(false, test.isBefore(new Instant(TEST_TIME1 - 1))); 325 assertEquals(false, test.isBefore(new Instant(TEST_TIME1))); 326 assertEquals(false, test.isBefore(new Instant(TEST_TIME1 + 1))); 327 328 assertEquals(false, test.isBefore(new Instant(TEST_TIME2 - 1))); 329 assertEquals(true, test.isBefore(new Instant(TEST_TIME2))); 330 assertEquals(true, test.isBefore(new Instant(TEST_TIME2 + 1))); 331 332 assertEquals(false, test.isBefore((ReadableInstant) null)); 333 } 334 335 public void testIsBefore_RInterval() { 336 MutableInterval test = new MutableInterval(TEST_TIME1, TEST_TIME2); 337 338 assertEquals(false, test.isBefore(new Interval(Long.MIN_VALUE, TEST_TIME1 - 1))); 339 assertEquals(false, test.isBefore(new Interval(Long.MIN_VALUE, TEST_TIME1))); 340 assertEquals(false, test.isBefore(new Interval(Long.MIN_VALUE, TEST_TIME1 + 1))); 341 342 assertEquals(false, test.isBefore(new Interval(TEST_TIME2 - 1, Long.MAX_VALUE))); 343 assertEquals(true, test.isBefore(new Interval(TEST_TIME2, Long.MAX_VALUE))); 344 assertEquals(true, test.isBefore(new Interval(TEST_TIME2 + 1, Long.MAX_VALUE))); 345 346 assertEquals(false, test.isBefore((ReadableInterval) null)); 347 } 348 349 public void testIsAfter_long() { 351 MutableInterval test = new MutableInterval(TEST_TIME1, TEST_TIME2); 352 353 assertEquals(true, test.isAfter(TEST_TIME1 - 1)); 354 assertEquals(false, test.isAfter(TEST_TIME1)); 355 assertEquals(false, test.isAfter(TEST_TIME1 + 1)); 356 357 assertEquals(false, test.isAfter(TEST_TIME2 - 1)); 358 assertEquals(false, test.isAfter(TEST_TIME2)); 359 assertEquals(false, test.isAfter(TEST_TIME2 + 1)); 360 } 361 362 public void testIsAfterNow() { 363 MutableInterval test = new MutableInterval(TEST_TIME1, TEST_TIME2); 364 365 DateTimeUtils.setCurrentMillisFixed(TEST_TIME1 - 1); 366 assertEquals(true, test.isAfterNow()); 367 DateTimeUtils.setCurrentMillisFixed(TEST_TIME1); 368 assertEquals(false, test.isAfterNow()); 369 DateTimeUtils.setCurrentMillisFixed(TEST_TIME1 + 1); 370 assertEquals(false, test.isAfterNow()); 371 } 372 373 public void testIsAfter_RI() { 374 MutableInterval test = new MutableInterval(TEST_TIME1, TEST_TIME2); 375 376 assertEquals(true, test.isAfter(new Instant(TEST_TIME1 - 1))); 377 assertEquals(false, test.isAfter(new Instant(TEST_TIME1))); 378 assertEquals(false, test.isAfter(new Instant(TEST_TIME1 + 1))); 379 380 assertEquals(false, test.isAfter(new Instant(TEST_TIME2 - 1))); 381 assertEquals(false, test.isAfter(new Instant(TEST_TIME2))); 382 assertEquals(false, test.isAfter(new Instant(TEST_TIME2 + 1))); 383 384 assertEquals(false, test.isAfter((ReadableInstant) null)); 385 } 386 387 public void testIsAfter_RInterval() { 388 MutableInterval test = new MutableInterval(TEST_TIME1, TEST_TIME2); 389 390 assertEquals(true, test.isAfter(new Interval(Long.MIN_VALUE, TEST_TIME1 - 1))); 391 assertEquals(true, test.isAfter(new Interval(Long.MIN_VALUE, TEST_TIME1))); 392 assertEquals(false, test.isAfter(new Interval(Long.MIN_VALUE, TEST_TIME1 + 1))); 393 394 assertEquals(false, test.isAfter(new Interval(TEST_TIME2 - 1, Long.MAX_VALUE))); 395 assertEquals(false, test.isAfter(new Interval(TEST_TIME2, Long.MAX_VALUE))); 396 assertEquals(false, test.isAfter(new Interval(TEST_TIME2 + 1, Long.MAX_VALUE))); 397 398 assertEquals(false, test.isAfter((ReadableInterval) null)); 399 } 400 401 public void testToInterval1() { 403 MutableInterval test = new MutableInterval(TEST_TIME1, TEST_TIME2, COPTIC_PARIS); 404 Interval result = test.toInterval(); 405 assertEquals(test, result); 406 } 407 408 public void testToMutableInterval1() { 410 MutableInterval test = new MutableInterval(TEST_TIME1, TEST_TIME2, COPTIC_PARIS); 411 MutableInterval result = test.toMutableInterval(); 412 assertEquals(test, result); 413 assertNotSame(test, result); 414 } 415 416 public void testToPeriod() { 418 DateTime dt1 = new DateTime(2004, 6, 9, 7, 8, 9, 10, COPTIC_PARIS); 419 DateTime dt2 = new DateTime(2005, 8, 13, 12, 14, 16, 18, COPTIC_PARIS); 420 MutableInterval base = new MutableInterval(dt1, dt2); 421 422 Period test = base.toPeriod(); 423 Period expected = new Period(dt1, dt2, PeriodType.standard()); 424 assertEquals(expected, test); 425 } 426 427 public void testToPeriod_PeriodType1() { 429 DateTime dt1 = new DateTime(2004, 6, 9, 7, 8, 9, 10, COPTIC_PARIS); 430 DateTime dt2 = new DateTime(2005, 8, 13, 12, 14, 16, 18, COPTIC_PARIS); 431 MutableInterval base = new MutableInterval(dt1, dt2); 432 433 Period test = base.toPeriod(null); 434 Period expected = new Period(dt1, dt2, PeriodType.standard()); 435 assertEquals(expected, test); 436 } 437 438 public void testToPeriod_PeriodType2() { 439 DateTime dt1 = new DateTime(2004, 6, 9, 7, 8, 9, 10); 440 DateTime dt2 = new DateTime(2005, 8, 13, 12, 14, 16, 18); 441 MutableInterval base = new MutableInterval(dt1, dt2); 442 443 Period test = base.toPeriod(PeriodType.yearWeekDayTime()); 444 Period expected = new Period(dt1, dt2, PeriodType.yearWeekDayTime()); 445 assertEquals(expected, test); 446 } 447 448 public void testSerialization() throws Exception { 450 MutableInterval test = new MutableInterval(TEST_TIME1, TEST_TIME2); 451 452 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 453 ObjectOutputStream oos = new ObjectOutputStream (baos); 454 oos.writeObject(test); 455 byte[] bytes = baos.toByteArray(); 456 oos.close(); 457 458 ByteArrayInputStream bais = new ByteArrayInputStream (bytes); 459 ObjectInputStream ois = new ObjectInputStream (bais); 460 MutableInterval result = (MutableInterval) ois.readObject(); 461 ois.close(); 462 463 assertEquals(test, result); 464 } 465 466 public void testToString() { 468 DateTime dt1 = new DateTime(2004, 6, 9, 7, 8, 9, 10, DateTimeZone.UTC); 469 DateTime dt2 = new DateTime(2005, 8, 13, 12, 14, 16, 18, DateTimeZone.UTC); 470 MutableInterval test = new MutableInterval(dt1, dt2); 471 assertEquals("2004-06-09T07:08:09.010/2005-08-13T12:14:16.018", test.toString()); 472 } 473 474 public void testCopy() { 476 MutableInterval test = new MutableInterval(123L, 456L, COPTIC_PARIS); 477 MutableInterval cloned = test.copy(); 478 assertEquals(test, cloned); 479 assertNotSame(test, cloned); 480 } 481 public void testClone() { 482 MutableInterval test = new MutableInterval(123L, 456L, COPTIC_PARIS); 483 MutableInterval cloned = (MutableInterval) test.clone(); 484 assertEquals(test, cloned); 485 assertNotSame(test, cloned); 486 } 487 488 489 } 490 | Popular Tags |