001package ezvcard;
002
003import java.io.File;
004import java.io.IOException;
005import java.io.OutputStream;
006import java.io.Writer;
007import java.util.AbstractList;
008import java.util.ArrayList;
009import java.util.Arrays;
010import java.util.Collection;
011import java.util.Collections;
012import java.util.Date;
013import java.util.HashSet;
014import java.util.Iterator;
015import java.util.List;
016import java.util.Map;
017import java.util.Set;
018
019import javax.xml.transform.TransformerException;
020
021import ezvcard.io.html.HCardPage;
022import ezvcard.io.json.JCardWriter;
023import ezvcard.io.text.VCardWriter;
024import ezvcard.io.xml.XCardWriter;
025import ezvcard.parameter.EmailType;
026import ezvcard.parameter.TelephoneType;
027import ezvcard.parameter.VCardParameters;
028import ezvcard.property.Address;
029import ezvcard.property.Agent;
030import ezvcard.property.Anniversary;
031import ezvcard.property.Birthday;
032import ezvcard.property.Birthplace;
033import ezvcard.property.CalendarRequestUri;
034import ezvcard.property.CalendarUri;
035import ezvcard.property.Categories;
036import ezvcard.property.Classification;
037import ezvcard.property.ClientPidMap;
038import ezvcard.property.Deathdate;
039import ezvcard.property.Deathplace;
040import ezvcard.property.Email;
041import ezvcard.property.Expertise;
042import ezvcard.property.FormattedName;
043import ezvcard.property.FreeBusyUrl;
044import ezvcard.property.Gender;
045import ezvcard.property.Geo;
046import ezvcard.property.HasAltId;
047import ezvcard.property.Hobby;
048import ezvcard.property.Impp;
049import ezvcard.property.Interest;
050import ezvcard.property.Key;
051import ezvcard.property.Kind;
052import ezvcard.property.Label;
053import ezvcard.property.Language;
054import ezvcard.property.Logo;
055import ezvcard.property.Mailer;
056import ezvcard.property.Member;
057import ezvcard.property.Nickname;
058import ezvcard.property.Note;
059import ezvcard.property.OrgDirectory;
060import ezvcard.property.Organization;
061import ezvcard.property.Photo;
062import ezvcard.property.ProductId;
063import ezvcard.property.Profile;
064import ezvcard.property.RawProperty;
065import ezvcard.property.Related;
066import ezvcard.property.Revision;
067import ezvcard.property.Role;
068import ezvcard.property.SortString;
069import ezvcard.property.Sound;
070import ezvcard.property.Source;
071import ezvcard.property.SourceDisplayText;
072import ezvcard.property.StructuredName;
073import ezvcard.property.Telephone;
074import ezvcard.property.Timezone;
075import ezvcard.property.Title;
076import ezvcard.property.Uid;
077import ezvcard.property.Url;
078import ezvcard.property.VCardProperty;
079import ezvcard.property.Xml;
080import ezvcard.util.ListMultimap;
081import ezvcard.util.StringUtils;
082
083/*
084 Copyright (c) 2012-2018, Michael Angstadt
085 All rights reserved.
086
087 Redistribution and use in source and binary forms, with or without
088 modification, are permitted provided that the following conditions are met: 
089
090 1. Redistributions of source code must retain the above copyright notice, this
091 list of conditions and the following disclaimer. 
092 2. Redistributions in binary form must reproduce the above copyright notice,
093 this list of conditions and the following disclaimer in the documentation
094 and/or other materials provided with the distribution. 
095
096 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
097 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
098 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
099 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
100 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
105 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
106
107 The views and conclusions contained in the software and documentation are those
108 of the authors and should not be interpreted as representing official policies, 
109 either expressed or implied, of the FreeBSD Project.
110 */
111
112/**
113 * Represents a vCard.
114 * @author Michael Angstadt
115 */
116public class VCard implements Iterable<VCardProperty> {
117        private VCardVersion version;
118        private final ListMultimap<Class<? extends VCardProperty>, VCardProperty> properties = new ListMultimap<Class<? extends VCardProperty>, VCardProperty>();
119
120        /**
121         * Creates a new vCard set to version 3.0.
122         */
123        public VCard() {
124                this(VCardVersion.V3_0);
125        }
126
127        /**
128         * Creates a new vCard.
129         * @param version the version to assign to the vCard
130         */
131        public VCard(VCardVersion version) {
132                this.version = version;
133        }
134
135        /**
136         * Creates a deep copy of the given vCard.
137         * @param original the vCard to copy
138         */
139        public VCard(VCard original) {
140                version = original.version;
141                for (VCardProperty property : original.getProperties()) {
142                        addProperty(property.copy());
143                }
144        }
145
146        /**
147         * <p>
148         * Marshals this vCard to its text representation.
149         * </p>
150         * <p>
151         * The vCard will be marshalled to whatever vCard version is assigned to
152         * this object (see {@link #setVersion(VCardVersion)}). If no version is
153         * set, then it will be marshalled to 3.0.
154         * </p>
155         * <p>
156         * Use the {@link VCardWriter} class for more control over the marshalling
157         * process and to write multiple vCards to the same stream.
158         * </p>
159         * @return the vCard string
160         * @see VCardWriter
161         * @see <a href="http://www.imc.org/pdi/vcard-21.rtf">vCard 2.1</a>
162         * @see <a href="http://tools.ietf.org/html/rfc2426">RFC 2426 (3.0)</a>
163         * @see <a href="http://tools.ietf.org/html/rfc6350">RFC 6350 (4.0)</a>
164         */
165        public String write() {
166                return Ezvcard.write(this).go();
167        }
168
169        /**
170         * <p>
171         * Marshals this vCard to its text representation.
172         * </p>
173         * <p>
174         * The vCard will be marshalled to whatever vCard version is assigned to
175         * this object (see {@link #setVersion(VCardVersion)}). If no version is
176         * set, then it will be marshalled to 3.0.
177         * </p>
178         * <p>
179         * Use the {@link VCardWriter} class for more control over the marshalling
180         * process and to write multiple vCards to the same stream.
181         * </p>
182         * @param file the file to write the vCard to
183         * @throws IOException if there's a problem writing to the file
184         * @see VCardWriter
185         * @see <a href="http://www.imc.org/pdi/vcard-21.rtf">vCard 2.1</a>
186         * @see <a href="http://tools.ietf.org/html/rfc2426">RFC 2426 (3.0)</a>
187         * @see <a href="http://tools.ietf.org/html/rfc6350">RFC 6350 (4.0)</a>
188         */
189        public void write(File file) throws IOException {
190                Ezvcard.write(this).go(file);
191        }
192
193        /**
194         * <p>
195         * Marshals this vCard to its text representation.
196         * </p>
197         * <p>
198         * The vCard will be marshalled to whatever vCard version is assigned to
199         * this object (see {@link #setVersion(VCardVersion)}). If no version is
200         * set, then it will be marshalled to 3.0.
201         * </p>
202         * <p>
203         * Use the {@link VCardWriter} class for more control over the marshalling
204         * process and to write multiple vCards to the same stream.
205         * </p>
206         * @param out the output stream to write the vCard to
207         * @see VCardWriter
208         * @throws IOException if there's a problem writing to the output stream
209         * @see <a href="http://www.imc.org/pdi/vcard-21.rtf">vCard 2.1</a>
210         * @see <a href="http://tools.ietf.org/html/rfc2426">RFC 2426 (3.0)</a>
211         * @see <a href="http://tools.ietf.org/html/rfc6350">RFC 6350 (4.0)</a>
212         */
213        public void write(OutputStream out) throws IOException {
214                Ezvcard.write(this).go(out);
215        }
216
217        /**
218         * <p>
219         * Marshals this vCard to its text representation.
220         * </p>
221         * <p>
222         * The vCard will be marshalled to whatever vCard version is assigned to
223         * this object (see {@link #setVersion(VCardVersion)}). If no version is
224         * set, then it will be marshalled to 3.0.
225         * </p>
226         * <p>
227         * Use the {@link VCardWriter} class for more control over the marshalling
228         * process and to write multiple vCards to the same stream.
229         * </p>
230         * @param writer the writer to write the vCard to
231         * @throws IOException if there's a problem writing to the writer
232         * @see VCardWriter
233         * @see <a href="http://www.imc.org/pdi/vcard-21.rtf">vCard 2.1</a>
234         * @see <a href="http://tools.ietf.org/html/rfc2426">RFC 2426 (3.0)</a>
235         * @see <a href="http://tools.ietf.org/html/rfc6350">RFC 6350 (4.0)</a>
236         */
237        public void write(Writer writer) throws IOException {
238                Ezvcard.write(this).go(writer);
239        }
240
241        /**
242         * <p>
243         * Marshals this vCard to its XML representation (xCard).
244         * </p>
245         * <p>
246         * Use the {@link XCardWriter} class for more control over the marshalling
247         * process and to write multiple vCards to the same stream.
248         * </p>
249         * @return the vCard XML document
250         * @see XCardWriter
251         * @see <a href="http://tools.ietf.org/html/rfc6351">RFC 6351</a>
252         */
253        public String writeXml() {
254                return Ezvcard.writeXml(this).indent(2).go();
255        }
256
257        /**
258         * <p>
259         * Marshals this vCard to its XML representation (xCard).
260         * </p>
261         * <p>
262         * Use the {@link XCardWriter} class for more control over the marshalling
263         * process and to write multiple vCards to the same stream.
264         * </p>
265         * @param file the file to write to
266         * @throws IOException if there's a problem writing to the file
267         * @throws TransformerException if there's a problem writing the vCard
268         * @see XCardWriter
269         * @see <a href="http://tools.ietf.org/html/rfc6351">RFC 6351</a>
270         */
271        public void writeXml(File file) throws IOException, TransformerException {
272                Ezvcard.writeXml(this).indent(2).go(file);
273        }
274
275        /**
276         * <p>
277         * Marshals this vCard to its XML representation (xCard).
278         * </p>
279         * <p>
280         * Use the {@link XCardWriter} class for more control over the marshalling
281         * process and to write multiple vCards to the same stream.
282         * </p>
283         * @param out the output stream to write the vCard to
284         * @throws TransformerException if there's a problem writing to the output
285         * stream
286         * @see XCardWriter
287         * @see <a href="http://tools.ietf.org/html/rfc6351">RFC 6351</a>
288         */
289        public void writeXml(OutputStream out) throws TransformerException {
290                Ezvcard.writeXml(this).indent(2).go(out);
291        }
292
293        /**
294         * <p>
295         * Marshals this vCard to its XML representation (xCard).
296         * </p>
297         * <p>
298         * Use the {@link XCardWriter} class for more control over the marshalling
299         * process and to write multiple vCards to the same stream.
300         * </p>
301         * @param writer the writer to write the vCard to
302         * @throws TransformerException if there's a problem writing to the writer
303         * @see XCardWriter
304         * @see <a href="http://tools.ietf.org/html/rfc6351">RFC 6351</a>
305         */
306        public void writeXml(Writer writer) throws TransformerException {
307                Ezvcard.writeXml(this).indent(2).go(writer);
308        }
309
310        /**
311         * <p>
312         * Marshals this vCard to a basic HTML page (hCard).
313         * </p>
314         * <p>
315         * Use the {@link HCardPage} class for more control over the marshalling
316         * process and to write multiple vCards to the same stream.
317         * </p>
318         * @return the HTML page
319         * @see HCardPage
320         * @see <a href="http://microformats.org/wiki/hcard">hCard 1.0</a>
321         */
322        public String writeHtml() {
323                return Ezvcard.writeHtml(this).go();
324        }
325
326        /**
327         * <p>
328         * Marshals this vCard to a basic HTML page (hCard).
329         * </p>
330         * <p>
331         * Use the {@link HCardPage} class for more control over the marshalling
332         * process and to write multiple vCards to the same stream.
333         * </p>
334         * @param file the file to write to
335         * @throws IOException if there's a problem writing to the file
336         * @see HCardPage
337         * @see <a href="http://microformats.org/wiki/hcard">hCard 1.0</a>
338         */
339        public void writeHtml(File file) throws IOException {
340                Ezvcard.writeHtml(this).go(file);
341        }
342
343        /**
344         * <p>
345         * Marshals this vCard to a basic HTML page (hCard).
346         * </p>
347         * <p>
348         * Use the {@link HCardPage} class for more control over the marshalling
349         * process and to write multiple vCards to the same stream.
350         * </p>
351         * @param out the output stream to write to
352         * @throws IOException if there's a problem writing to the output stream
353         * @see HCardPage
354         * @see <a href="http://microformats.org/wiki/hcard">hCard 1.0</a>
355         */
356        public void writeHtml(OutputStream out) throws IOException {
357                Ezvcard.writeHtml(this).go(out);
358        }
359
360        /**
361         * <p>
362         * Marshals this vCard to a basic HTML page (hCard).
363         * </p>
364         * <p>
365         * Use the {@link HCardPage} class for more control over the marshalling
366         * process and to write multiple vCards to the same stream.
367         * </p>
368         * @param writer the writer to write to
369         * @throws IOException if there's a problem writing to the writer
370         * @see HCardPage
371         * @see <a href="http://microformats.org/wiki/hcard">hCard 1.0</a>
372         */
373        public void writeHtml(Writer writer) throws IOException {
374                Ezvcard.writeHtml(this).go(writer);
375        }
376
377        /**
378         * <p>
379         * Marshals this vCard to its JSON representation (jCard).
380         * </p>
381         * <p>
382         * Use the {@link JCardWriter} class for more control over the marshalling
383         * process and to write multiple vCards to the same stream.
384         * </p>
385         * @return the JSON string
386         * @see JCardWriter
387         * @see <a href="http://tools.ietf.org/html/rfc7095">RFC 7095</a>
388         */
389        public String writeJson() {
390                return Ezvcard.writeJson(this).go();
391        }
392
393        /**
394         * <p>
395         * Marshals this vCard to its JSON representation (jCard).
396         * </p>
397         * <p>
398         * Use the {@link JCardWriter} class for more control over the marshalling
399         * process and to write multiple vCards to the same stream.
400         * </p>
401         * @param file the file to write the vCard to
402         * @throws IOException if there's a problem writing to the file
403         * @see JCardWriter
404         * @see <a href="http://tools.ietf.org/html/rfc7095">RFC 7095</a>
405         */
406        public void writeJson(File file) throws IOException {
407                Ezvcard.writeJson(this).go(file);
408        }
409
410        /**
411         * <p>
412         * Marshals this vCard to its JSON representation (jCard).
413         * </p>
414         * <p>
415         * Use the {@link JCardWriter} class for more control over the marshalling
416         * process and to write multiple vCards to the same stream.
417         * </p>
418         * @param out the output stream to write the vCard to
419         * @see JCardWriter
420         * @throws IOException if there's a problem writing to the output stream
421         * @see <a href="http://tools.ietf.org/html/rfc7095">RFC 7095</a>
422         */
423        public void writeJson(OutputStream out) throws IOException {
424                Ezvcard.writeJson(this).go(out);
425        }
426
427        /**
428         * <p>
429         * Marshals this vCard to its JSON representation (jCard).
430         * </p>
431         * <p>
432         * Use the {@link JCardWriter} class for more control over the marshalling
433         * process and to write multiple vCards to the same stream.
434         * </p>
435         * @param writer the writer to write the vCard to
436         * @throws IOException if there's a problem writing to the writer
437         * @see JCardWriter
438         * @see <a href="http://tools.ietf.org/html/rfc7095">RFC 7095</a>
439         */
440        public void writeJson(Writer writer) throws IOException {
441                Ezvcard.writeJson(this).go(writer);
442        }
443
444        /**
445         * Gets the version attached to this vCard.
446         * @return the vCard version
447         */
448        public VCardVersion getVersion() {
449                return version;
450        }
451
452        /**
453         * <p>
454         * Sets the version of this vCard.
455         * </p>
456         * <p>
457         * When marshalling a vCard with the {@link VCardWriter} class, use the
458         * {@link VCardWriter#setTargetVersion setTargetVersion} method to define
459         * what version the vCard should be marshalled as. {@link VCardWriter}
460         * <b>does not</b> look at the version that is set on the VCard object.
461         * </p>
462         * @param version the vCard version
463         */
464        public void setVersion(VCardVersion version) {
465                this.version = version;
466        }
467
468        /**
469         * <p>
470         * Gets the type of entity this vCard represents.
471         * </p>
472         * <p>
473         * <b>Property name:</b> {@code KIND}<br>
474         * <b>Supported versions:</b> {@code 4.0}
475         * </p>
476         * @return the kind property or null if not set
477         * @see <a href="http://tools.ietf.org/html/rfc6350#page-25">RFC 6350
478         * p.25</a>
479         */
480        public Kind getKind() {
481                return getProperty(Kind.class);
482        }
483
484        /**
485         * <p>
486         * Sets the type of entity this vCard represents.
487         * </p>
488         * <p>
489         * <b>Property name:</b> {@code KIND}<br>
490         * <b>Supported versions:</b> {@code 4.0}
491         * </p>
492         * @param kind the kind property or null to remove
493         * @see <a href="http://tools.ietf.org/html/rfc6350#page-25">RFC 6350
494         * p.25</a>
495         */
496        public void setKind(Kind kind) {
497                setProperty(Kind.class, kind);
498        }
499
500        /**
501         * <p>
502         * Gets the gender of the person.
503         * </p>
504         * <p>
505         * <b>Property name:</b> {@code GENDER}<br>
506         * <b>Supported versions:</b> {@code 4.0}
507         * </p>
508         * @return the gender property or null if not set
509         * @see <a href="http://tools.ietf.org/html/rfc6350#page-32">RFC 6350
510         * p.32</a>
511         */
512        public Gender getGender() {
513                return getProperty(Gender.class);
514        }
515
516        /**
517         * <p>
518         * Sets the gender of the person.
519         * </p>
520         * <p>
521         * <b>Property name:</b> {@code GENDER}<br>
522         * <b>Supported versions:</b> {@code 4.0}
523         * </p>
524         * @param gender the gender property or null to remove
525         * @see <a href="http://tools.ietf.org/html/rfc6350#page-32">RFC 6350
526         * p.32</a>
527         */
528        public void setGender(Gender gender) {
529                setProperty(Gender.class, gender);
530        }
531
532        /**
533         * <p>
534         * Gets the members of the group that this vCard represents.
535         * </p>
536         * <p>
537         * Note: If a vCard has any {@link Member} properties, then it must also
538         * have a {@link Kind} property whose value is set to "group".
539         * </p>
540         * <p>
541         * <b>Property name:</b> {@code MEMBER}<br>
542         * <b>Supported versions:</b> {@code 4.0}
543         * </p>
544         * @return the members properties (any changes made this list will affect
545         * the {@link VCard} object and vice versa)
546         * @see <a href="http://tools.ietf.org/html/rfc6350#page-41">RFC 6350
547         * p.41</a>
548         */
549        public List<Member> getMembers() {
550                return getProperties(Member.class);
551        }
552
553        /**
554         * <p>
555         * Adds a member to the group that this vCard represents.
556         * </p>
557         * <p>
558         * Note: If a vCard has any {@link Member} properties, then it must also
559         * have a {@link Kind} property whose value is set to "group".
560         * </p>
561         * <p>
562         * <b>Property name:</b> {@code MEMBER}<br>
563         * <b>Supported versions:</b> {@code 4.0}
564         * </p>
565         * @param member the member property to add
566         * @see <a href="http://tools.ietf.org/html/rfc6350#page-41">RFC 6350
567         * p.41</a>
568         */
569        public void addMember(Member member) {
570                addProperty(member);
571        }
572
573        /**
574         * <p>
575         * Adds a member to the group that this vCard represents.
576         * </p>
577         * <p>
578         * Note: If a vCard has any {@link Member} properties, then it must also
579         * have a {@link Kind} property whose value is set to "group".
580         * </p>
581         * <p>
582         * <b>Property name:</b> {@code MEMBER}<br>
583         * <b>Supported versions:</b> {@code 4.0}
584         * </p>
585         * @param altRepresentations the alternative representations of the same
586         * value. These properties contain the same information, but in different
587         * forms (such as different languages). See {@link VCardParameters#getAltId
588         * this description of the ALTID parameter} for more information. Note that
589         * this method automatically assigns an appropriate ALTID parameter to each
590         * property.
591         * @see <a href="http://tools.ietf.org/html/rfc6350#page-41">RFC 6350
592         * p.41</a>
593         */
594        public void addMemberAlt(Member... altRepresentations) {
595                addPropertyAlt(Member.class, altRepresentations);
596        }
597
598        /**
599         * <p>
600         * Gets the profile property. This property simply identifies the vCard as a
601         * vCard.
602         * </p>
603         * <p>
604         * <b>Property name:</b> {@code PROFILE}<br>
605         * <b>Supported versions:</b> {@code 3.0}
606         * </p>
607         * @return the profile property or null if not set
608         * @see <a href="http://tools.ietf.org/html/rfc2426#page-5">RFC 2426 p.5</a>
609         */
610        public Profile getProfile() {
611                return getProperty(Profile.class);
612        }
613
614        /**
615         * <p>
616         * Sets the profile property. This property simply identifies the vCard as a
617         * vCard.
618         * </p>
619         * <p>
620         * <b>Property name:</b> {@code PROFILE}<br>
621         * <b>Supported versions:</b> {@code 3.0}
622         * </p>
623         * @see <a href="http://tools.ietf.org/html/rfc2426#page-5">RFC 2426 p.5</a>
624         * @param profile the profile property or null to remove
625         */
626        public void setProfile(Profile profile) {
627                setProperty(Profile.class, profile);
628        }
629
630        /**
631         * <p>
632         * Gets the classification of the vCard, which describes the sensitivity of
633         * the information in the vCard.
634         * </p>
635         * <p>
636         * <b>Property name:</b> {@code CLASS}<br>
637         * <b>Supported versions:</b> {@code 3.0}
638         * </p>
639         * @return the classification property or null if not set
640         * @see <a href="http://tools.ietf.org/html/rfc2426#page-26">RFC 2426
641         * p.26</a>
642         */
643        public Classification getClassification() {
644                return getProperty(Classification.class);
645        }
646
647        /**
648         * <p>
649         * Sets the classification of the vCard, which describes the sensitivity of
650         * the information in the vCard.
651         * </p>
652         * <p>
653         * <b>Property name:</b> {@code CLASS}<br>
654         * <b>Supported versions:</b> {@code 3.0}
655         * </p>
656         * @param classification the classification property or null to remove
657         * @see <a href="http://tools.ietf.org/html/rfc2426#page-26">RFC 2426
658         * p.26</a>
659         */
660        public void setClassification(Classification classification) {
661                setProperty(Classification.class, classification);
662        }
663
664        /**
665         * <p>
666         * Sets the classification of the vCard, which describes the sensitivity of
667         * the information in the vCard.
668         * </p>
669         * <p>
670         * <b>Supported versions:</b> {@code 3.0}<br>
671         * <b>Property name:</b> {@code CLASS}
672         * </p>
673         * @param classification the classification (e.g. "PUBLIC", "PRIVATE",
674         * "CONFIDENTIAL") or null to remove
675         * @return the property object that was created
676         * @see <a href="http://tools.ietf.org/html/rfc2426#page-26">RFC 2426
677         * p.26</a>
678         */
679        public Classification setClassification(String classification) {
680                Classification type = (classification == null) ? null : new Classification(classification);
681                setClassification(type);
682                return type;
683        }
684
685        /**
686         * <p>
687         * Gets the URIs that can be used to retrieve the most up-to-date version of
688         * the person's vCard.
689         * </p>
690         * <p>
691         * <b>Property name:</b> {@code SOURCE} <b>Supported versions:</b>
692         * {@code 3.0, 4.0}
693         * </p>
694         * @return the source properties (any changes made this list will affect the
695         * {@link VCard} object and vice versa)
696         * @see <a href="http://tools.ietf.org/html/rfc6350#page-24">RFC 6350
697         * p.24</a>
698         * @see <a href="http://tools.ietf.org/html/rfc2426#page-5">RFC 2426 p.5</a>
699         */
700        public List<Source> getSources() {
701                return getProperties(Source.class);
702        }
703
704        /**
705         * <p>
706         * Adds a URI that can be used to retrieve the most up-to-date version of
707         * the person's vCard.
708         * </p>
709         * <p>
710         * <b>Property name:</b> {@code SOURCE} <b>Supported versions:</b>
711         * {@code 3.0, 4.0}
712         * </p>
713         * @param source the source property
714         * @see <a href="http://tools.ietf.org/html/rfc6350#page-24">RFC 6350
715         * p.24</a>
716         * @see <a href="http://tools.ietf.org/html/rfc2426#page-5">RFC 2426 p.5</a>
717         */
718        public void addSource(Source source) {
719                addProperty(source);
720        }
721
722        /**
723         * <p>
724         * Adds a URI that can be used to retrieve the most up-to-date version of
725         * the person's vCard.
726         * </p>
727         * <p>
728         * <b>Property name:</b> {@code SOURCE}<br>
729         * <b>Supported versions:</b> {@code 3.0, 4.0}
730         * </p>
731         * @param source the source URI (e.g. "http://example.com/vcard.vcf")
732         * @return the property object that was created
733         * @see <a href="http://tools.ietf.org/html/rfc6350#page-24">RFC 6350
734         * p.24</a>
735         * @see <a href="http://tools.ietf.org/html/rfc2426#page-5">RFC 2426 p.5</a>
736         */
737        public Source addSource(String source) {
738                Source type = new Source(source);
739                addSource(type);
740                return type;
741        }
742
743        /**
744         * <p>
745         * Adds a URI that can be used to retrieve the most up-to-date version of
746         * the person's vCard.
747         * </p>
748         * <p>
749         * <b>Property name:</b> {@code SOURCE}<br>
750         * <b>Supported versions:</b> {@code 4.0*}<br>
751         * <i>* Only 4.0 supports alternative representations</i>
752         * </p>
753         * @param altRepresentations the alternative representations of the same
754         * value. These properties contain the same information, but in different
755         * forms (such as different languages). See {@link VCardParameters#getAltId
756         * this description of the ALTID parameter} for more information. Note that
757         * this method automatically assigns an appropriate ALTID parameter to each
758         * property.
759         * @see <a href="http://tools.ietf.org/html/rfc6350#page-24">RFC 6350
760         * p.24</a>
761         */
762        public void addSourceAlt(Source... altRepresentations) {
763                addPropertyAlt(Source.class, altRepresentations);
764        }
765
766        /**
767         * <p>
768         * Gets a textual representation of the {@link Source} property.
769         * </p>
770         * <p>
771         * <b>Property name:</b> {@code NAME}<br>
772         * <b>Supported versions:</b> {@code 3.0}
773         * </p>
774         * @return the property or null if not set
775         * @see <a href="http://tools.ietf.org/html/rfc2426#page-5">RFC 2426 p.5</a>
776         */
777        public SourceDisplayText getSourceDisplayText() {
778                return getProperty(SourceDisplayText.class);
779        }
780
781        /**
782         * <p>
783         * Sets a textual representation of the {@link Source} property.
784         * </p>
785         * <p>
786         * <b>Property name:</b> {@code NAME}<br>
787         * <b>Supported versions:</b> {@code 3.0}
788         * </p>
789         * @param sourceDisplayText the property null to remove
790         * @see <a href="http://tools.ietf.org/html/rfc2426#page-5">RFC 2426 p.5</a>
791         */
792        public void setSourceDisplayText(SourceDisplayText sourceDisplayText) {
793                setProperty(SourceDisplayText.class, sourceDisplayText);
794        }
795
796        /**
797         * <p>
798         * Sets a textual representation of the {@link Source} property.
799         * </p>
800         * <p>
801         * <b>Property name:</b> {@code NAME}<br>
802         * <b>Supported versions:</b> {@code 3.0}
803         * </p>
804         * @param sourceDisplayText a textual representation of the vCard source or
805         * null to remove
806         * @return the property object that was created
807         * @see <a href="http://tools.ietf.org/html/rfc2426#page-5">RFC 2426 p.5</a>
808         */
809        public SourceDisplayText setSourceDisplayText(String sourceDisplayText) {
810                SourceDisplayText type = (sourceDisplayText == null) ? null : new SourceDisplayText(sourceDisplayText);
811                setSourceDisplayText(type);
812                return type;
813        }
814
815        /**
816         * <p>
817         * Gets all instances of the {@link FormattedName} property.
818         * </p>
819         * <p>
820         * Version 4.0 vCards may have multiple instances if alternative
821         * representations are defined (see
822         * {@link #addFormattedNameAlt(FormattedName...) addFormattedNameAlt}) or if
823         * properties with different TYPE parameters are defined.
824         * </p>
825         * <p>
826         * <b>Property name:</b> {@code FN}<br>
827         * <b>Supported versions:</b> {@code 4.0*}<br>
828         * <i>* Only 4.0 supports multiple instances</i>
829         * </p>
830         * @return the formatted name properties (any changes made this list will
831         * affect the {@link VCard} object and vice versa)
832         * @see <a href="http://tools.ietf.org/html/rfc6350#page-28">RFC 6350
833         * p.28</a>
834         * @see <a href="http://tools.ietf.org/html/rfc2426#page-8">RFC 2426 p.8</a>
835         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.9</a>
836         */
837        public List<FormattedName> getFormattedNames() {
838                return getProperties(FormattedName.class);
839        }
840
841        /**
842         * <p>
843         * Gets the person's full name.
844         * </p>
845         * <p>
846         * <b>Property name:</b> {@code FN}<br>
847         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
848         * </p>
849         * @return the first formatted name property or null if not set
850         * @see <a href="http://tools.ietf.org/html/rfc6350#page-28">RFC 6350
851         * p.28</a>
852         * @see <a href="http://tools.ietf.org/html/rfc2426#page-8">RFC 2426 p.8</a>
853         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.9</a>
854         */
855        public FormattedName getFormattedName() {
856                return getProperty(FormattedName.class);
857        }
858
859        /**
860         * <p>
861         * Sets the person's full name.
862         * </p>
863         * <p>
864         * <b>Property name:</b> {@code FN}<br>
865         * <b>Supported versions:</b> {@code 4.0*}<br>
866         * <i>* Only 4.0 supports alternative representations</i>
867         * </p>
868         * @param altRepresentations the alternative representations of the same
869         * value. These properties contain the same information, but in different
870         * forms (such as different languages). See {@link VCardParameters#getAltId
871         * this description of the ALTID parameter} for more information. Note that
872         * this method automatically assigns an appropriate ALTID parameter to each
873         * property.
874         * @see <a href="http://tools.ietf.org/html/rfc6350#page-28">RFC 6350
875         * p.28</a>
876         * @see <a href="http://tools.ietf.org/html/rfc2426#page-8">RFC 2426 p.8</a>
877         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.9</a>
878         */
879        public void setFormattedNameAlt(FormattedName... altRepresentations) {
880                setPropertyAlt(FormattedName.class, altRepresentations);
881        }
882
883        /**
884         * <p>
885         * Adds a version of the person's full name.
886         * </p>
887         * <p>
888         * <b>Property name:</b> {@code FN}<br>
889         * <b>Supported versions:</b> {@code 4.0*}<br>
890         * <i>* Only 4.0 supports alternative representations</i>
891         * </p>
892         * @param altRepresentations the alternative representations of the same
893         * value. These properties contain the same information, but in different
894         * forms (such as different languages). See {@link VCardParameters#getAltId
895         * this description of the ALTID parameter} for more information. Note that
896         * this method automatically assigns an appropriate ALTID parameter to each
897         * property.
898         * @see <a href="http://tools.ietf.org/html/rfc6350#page-28">RFC 6350
899         * p.28</a>
900         * @see <a href="http://tools.ietf.org/html/rfc2426#page-8">RFC 2426 p.8</a>
901         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.9</a>
902         */
903        public void addFormattedNameAlt(FormattedName... altRepresentations) {
904                addPropertyAlt(FormattedName.class, altRepresentations);
905        }
906
907        /**
908         * <p>
909         * Sets the person's full name.
910         * </p>
911         * <p>
912         * <b>Property name:</b> {@code FN}<br>
913         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
914         * </p>
915         * @param formattedName the formatted name property or null to remove
916         * @see <a href="http://tools.ietf.org/html/rfc6350#page-28">RFC 6350
917         * p.28</a>
918         * @see <a href="http://tools.ietf.org/html/rfc2426#page-8">RFC 2426 p.8</a>
919         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.9</a>
920         */
921        public void setFormattedName(FormattedName formattedName) {
922                setProperty(FormattedName.class, formattedName);
923        }
924
925        /**
926         * <p>
927         * Adds a version of the person's full name.
928         * </p>
929         * <p>
930         * <b>Property name:</b> {@code FN}<br>
931         * <b>Supported versions:</b> {@code 4.0*}<br>
932         * <i>* Only 4.0 supports multiple instances</i>
933         * </p>
934         * @param formattedName the formatted name property to add
935         * @see <a href="http://tools.ietf.org/html/rfc6350#page-28">RFC 6350
936         * p.28</a>
937         * @see <a href="http://tools.ietf.org/html/rfc2426#page-8">RFC 2426 p.8</a>
938         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.9</a>
939         */
940        public void addFormattedName(FormattedName formattedName) {
941                addProperty(formattedName);
942        }
943
944        /**
945         * <p>
946         * Sets the person's full name.
947         * </p>
948         * <p>
949         * <b>Property name:</b> {@code FN}<br>
950         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
951         * </p>
952         * @param formattedName the formatted name (e.g. "John Doe") or null to
953         * remove
954         * @return the property object that was created
955         * @see <a href="http://tools.ietf.org/html/rfc6350#page-28">RFC 6350
956         * p.28</a>
957         * @see <a href="http://tools.ietf.org/html/rfc2426#page-8">RFC 2426 p.8</a>
958         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.9</a>
959         */
960        public FormattedName setFormattedName(String formattedName) {
961                FormattedName type = (formattedName == null) ? null : new FormattedName(formattedName);
962                setFormattedName(type);
963                return type;
964        }
965
966        /**
967         * <p>
968         * Gets all structured name properties.
969         * </p>
970         * <p>
971         * Version 4.0 vCards may have multiple instances if alternative
972         * representations are defined (see
973         * {@link #setStructuredNameAlt(StructuredName...) setStructuredNameAlt}) or
974         * if properties with different TYPE parameters are defined.
975         * </p>
976         * <p>
977         * <b>Property name:</b> {@code N}<br>
978         * <b>Supported versions:</b> {@code 4.0*}<br>
979         * <i>* Only 4.0 supports alternative representations</i>
980         * </p>
981         * @return the structured name properties (any changes made this list will
982         * affect the {@link VCard} object and vice versa)
983         * @see <a href="http://tools.ietf.org/html/rfc6350#page-29">RFC 6350
984         * p.29</a>
985         * @see <a href="http://tools.ietf.org/html/rfc2426#page-9">RFC 2426 p.9</a>
986         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.9</a>
987         */
988        public List<StructuredName> getStructuredNames() {
989                return getProperties(StructuredName.class);
990        }
991
992        /**
993         * <p>
994         * Gets the individual components of the person's name.
995         * </p>
996         * <p>
997         * <b>Property name:</b> {@code N}<br>
998         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
999         * </p>
1000         * @return the first structured name property or null if not set
1001         * @see <a href="http://tools.ietf.org/html/rfc6350#page-29">RFC 6350
1002         * p.29</a>
1003         * @see <a href="http://tools.ietf.org/html/rfc2426#page-9">RFC 2426 p.9</a>
1004         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.9</a>
1005         */
1006        public StructuredName getStructuredName() {
1007                return getProperty(StructuredName.class);
1008        }
1009
1010        /**
1011         * <p>
1012         * Sets the individual components of the person's name.
1013         * </p>
1014         * <p>
1015         * <b>Property name:</b> {@code N}<br>
1016         * <b>Supported versions:</b> {@code 4.0*}<br>
1017         * <i>* Only 4.0 supports alternative representations</i>
1018         * </p>
1019         * @param altRepresentations the alternative representations of the same
1020         * value. These properties contain the same information, but in different
1021         * forms (such as different languages). See {@link VCardParameters#getAltId
1022         * this description of the ALTID parameter} for more information. Note that
1023         * this method automatically assigns an appropriate ALTID parameter to each
1024         * property.
1025         * @see <a href="http://tools.ietf.org/html/rfc6350#page-29">RFC 6350
1026         * p.29</a>
1027         * @see <a href="http://tools.ietf.org/html/rfc2426#page-9">RFC 2426 p.9</a>
1028         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.9</a>
1029         */
1030        public void setStructuredNameAlt(StructuredName... altRepresentations) {
1031                setPropertyAlt(StructuredName.class, altRepresentations);
1032        }
1033
1034        /**
1035         * Sets the individual components of the person's name.
1036         * <p>
1037         * <b>Property name:</b> {@code N}<br>
1038         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
1039         * </p>
1040         * @param structuredName the structured name property or null to remove
1041         */
1042        public void setStructuredName(StructuredName structuredName) {
1043                setProperty(StructuredName.class, structuredName);
1044        }
1045
1046        /**
1047         * <p>
1048         * Gets all instances of the {@link Nickname} property.
1049         * </p>
1050         * <p>
1051         * Version 4.0 vCards may have multiple instances if alternative
1052         * representations are defined (see {@link #setNicknameAlt(Nickname...)
1053         * setNicknameAlt}) or if properties with different TYPE parameters are
1054         * defined.
1055         * </p>
1056         * <p>
1057         * <b>Property name:</b> {@code NICKNAME}<br>
1058         * <b>Supported versions:</b> {@code 3.0, 4.0}
1059         * </p>
1060         * @return the nickname properties (any changes made this list will affect
1061         * the {@link VCard} object and vice versa)
1062         * @see <a href="http://tools.ietf.org/html/rfc6350#page-29">RFC 6350
1063         * p.29</a>
1064         * @see <a href="http://tools.ietf.org/html/rfc2426#page-9">RFC 2426 p.9</a>
1065         */
1066        public List<Nickname> getNicknames() {
1067                return getProperties(Nickname.class);
1068        }
1069
1070        /**
1071         * <p>
1072         * Gets the person's nicknames.
1073         * </p>
1074         * <p>
1075         * <b>Property name:</b> {@code NICKNAME}<br>
1076         * <b>Supported versions:</b> {@code 3.0, 4.0}
1077         * </p>
1078         * @return the nickname property (may contain multiple values) or null if
1079         * not set
1080         * @see <a href="http://tools.ietf.org/html/rfc6350#page-29">RFC 6350
1081         * p.29</a>
1082         * @see <a href="http://tools.ietf.org/html/rfc2426#page-9">RFC 2426 p.9</a>
1083         */
1084        public Nickname getNickname() {
1085                return getProperty(Nickname.class);
1086        }
1087
1088        /**
1089         * <p>
1090         * Sets the person's nicknames.
1091         * </p>
1092         * <p>
1093         * <b>Property name:</b> {@code NICKNAME}<br>
1094         * <b>Supported versions:</b> {@code 4.0*}<br>
1095         * <i>* Only 4.0 supports alternative representations</i>
1096         * </p>
1097         * @param altRepresentations the alternative representations of the same
1098         * value. These properties contain the same information, but in different
1099         * forms (such as different languages). See {@link VCardParameters#getAltId
1100         * this description of the ALTID parameter} for more information. Note that
1101         * this method automatically assigns an appropriate ALTID parameter to each
1102         * property.
1103         * @see <a href="http://tools.ietf.org/html/rfc6350#page-29">RFC 6350
1104         * p.29</a>
1105         * @see <a href="http://tools.ietf.org/html/rfc2426#page-9">RFC 2426 p.9</a>
1106         */
1107        public void setNicknameAlt(Nickname... altRepresentations) {
1108                setPropertyAlt(Nickname.class, altRepresentations);
1109        }
1110
1111        /**
1112         * <p>
1113         * Adds a collection of nicknames for the person.
1114         * </p>
1115         * <p>
1116         * <b>Property name:</b> {@code NICKNAME}<br>
1117         * <b>Supported versions:</b> {@code 4.0*}<br>
1118         * <i>* Only 4.0 supports alternative representations</i>
1119         * </p>
1120         * @param altRepresentations the alternative representations of the same
1121         * value. These properties contain the same information, but in different
1122         * forms (such as different languages). See {@link VCardParameters#getAltId
1123         * this description of the ALTID parameter} for more information. Note that
1124         * this method automatically assigns an appropriate ALTID parameter to each
1125         * property.
1126         * @see <a href="http://tools.ietf.org/html/rfc6350#page-29">RFC 6350
1127         * p.29</a>
1128         * @see <a href="http://tools.ietf.org/html/rfc2426#page-9">RFC 2426 p.9</a>
1129         */
1130        public void addNicknameAlt(Nickname... altRepresentations) {
1131                addPropertyAlt(Nickname.class, altRepresentations);
1132        }
1133
1134        /**
1135         * <p>
1136         * Sets the person's nicknames.
1137         * </p>
1138         * <p>
1139         * <b>Property name:</b> {@code NICKNAME}<br>
1140         * <b>Supported versions:</b> {@code 3.0, 4.0}
1141         * </p>
1142         * @param nickname the nickname property (may contain multiple values) or
1143         * null to remove
1144         * @see <a href="http://tools.ietf.org/html/rfc6350#page-29">RFC 6350
1145         * p.29</a>
1146         * @see <a href="http://tools.ietf.org/html/rfc2426#page-9">RFC 2426 p.9</a>
1147         */
1148        public void setNickname(Nickname nickname) {
1149                setProperty(Nickname.class, nickname);
1150        }
1151
1152        /**
1153         * <p>
1154         * Adds a set of nicknames for the person.
1155         * </p>
1156         * <p>
1157         * Note that only version 4.0 vCards support multiple instances of this
1158         * property.
1159         * </p>
1160         * <p>
1161         * <b>Property name:</b> {@code NICKNAME}<br>
1162         * <b>Supported versions:</b> {@code 4.0*}<br>
1163         * <i>* Only 4.0 supports multiple instances</i>
1164         * </p>
1165         * @param nickname the nickname property (may contain multiple values)
1166         * @see <a href="http://tools.ietf.org/html/rfc6350#page-29">RFC 6350
1167         * p.29</a>
1168         * @see <a href="http://tools.ietf.org/html/rfc2426#page-9">RFC 2426 p.9</a>
1169         */
1170        public void addNickname(Nickname nickname) {
1171                addProperty(nickname);
1172        }
1173
1174        /**
1175         * <p>
1176         * Sets the person's nicknames.
1177         * </p>
1178         * <p>
1179         * <b>Property name:</b> {@code NICKNAME}<br>
1180         * <b>Supported versions:</b> {@code 3.0, 4.0}
1181         * </p>
1182         * @param nicknames the nicknames (e.g. "John", "Jon")
1183         * @return the property object that was created
1184         * @see <a href="http://tools.ietf.org/html/rfc6350#page-29">RFC 6350
1185         * p.29</a>
1186         * @see <a href="http://tools.ietf.org/html/rfc2426#page-9">RFC 2426 p.9</a>
1187         */
1188        public Nickname setNickname(String... nicknames) {
1189                Nickname property = null;
1190                if (nicknames != null && nicknames.length > 0 && nicknames[0] != null) {
1191                        property = new Nickname();
1192                        property.getValues().addAll(Arrays.asList(nicknames));
1193                }
1194                setNickname(property);
1195                return property;
1196        }
1197
1198        /**
1199         * <p>
1200         * Gets the string that should be used to sort the vCard. This typically set
1201         * to the person's family name (last name).
1202         * </p>
1203         * <p>
1204         * For 4.0 vCards, this information is stored in the
1205         * {@link StructuredName#getSortAs} and/or {@link Organization#getSortAs}
1206         * methods.
1207         * </p>
1208         * <p>
1209         * <b>Property name:</b> {@code SORT-STRING}<br>
1210         * <b>Supported versions:</b> {@code 3.0}
1211         * </p>
1212         * @return the sort string property or null if not set
1213         * @see <a href="http://tools.ietf.org/html/rfc2426#page-22">RFC 2426
1214         * p.22</a>
1215         */
1216        public SortString getSortString() {
1217                return getProperty(SortString.class);
1218        }
1219
1220        /**
1221         * <p>
1222         * Sets the string that should be used to sort the vCard. This typically set
1223         * to the person's family name (last name).
1224         * </p>
1225         * <p>
1226         * For 4.0 vCards, this information is stored in the
1227         * {@link StructuredName#getSortAs} and/or {@link Organization#getSortAs}
1228         * methods.
1229         * </p>
1230         * <p>
1231         * <b>Property name:</b> {@code SORT-STRING}<br>
1232         * <b>Supported versions:</b> {@code 3.0}
1233         * </p>
1234         * @param sortString the sort string property or null to remove
1235         * @see <a href="http://tools.ietf.org/html/rfc2426#page-22">RFC 2426
1236         * p.22</a>
1237         */
1238        public void setSortString(SortString sortString) {
1239                setProperty(SortString.class, sortString);
1240        }
1241
1242        /**
1243         * <p>
1244         * Sets the string that should be used to sort the vCard. This typically set
1245         * to the person's family name (last name).
1246         * </p>
1247         * <p>
1248         * For 4.0 vCards, this information is stored in the
1249         * {@link StructuredName#getSortAs} and/or {@link Organization#getSortAs}
1250         * methods.
1251         * </p>
1252         * <p>
1253         * <b>Property name:</b> {@code SORT-STRING}<br>
1254         * <b>Supported versions:</b> {@code 3.0}
1255         * </p>
1256         * @param sortString the sort string (e.g. "Armour" if the person's last
1257         * name is "d'Armour") or null to remove
1258         * @return the property object that was created
1259         * @see <a href="http://tools.ietf.org/html/rfc2426#page-22">RFC 2426
1260         * p.22</a>
1261         */
1262        public SortString setSortString(String sortString) {
1263                SortString type = (sortString == null) ? null : new SortString(sortString);
1264                setSortString(type);
1265                return type;
1266        }
1267
1268        /**
1269         * <p>
1270         * Gets the titles associated with the person.
1271         * </p>
1272         * <p>
1273         * <b>Property name:</b> {@code TITLE}<br>
1274         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
1275         * </p>
1276         * @return the title properties (any changes made this list will affect the
1277         * {@link VCard} object and vice versa)
1278         * @see <a href="http://tools.ietf.org/html/rfc6350#page-39">RFC 6350
1279         * p.39</a>
1280         * @see <a href="http://tools.ietf.org/html/rfc2426#page-17">RFC 2426
1281         * p.17</a>
1282         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.17</a>
1283         */
1284        public List<Title> getTitles() {
1285                return getProperties(Title.class);
1286        }
1287
1288        /**
1289         * <p>
1290         * Adds a title associated with the person.
1291         * </p>
1292         * <p>
1293         * <b>Property name:</b> {@code TITLE}<br>
1294         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
1295         * </p>
1296         * @param title the title property to add
1297         * @see <a href="http://tools.ietf.org/html/rfc6350#page-39">RFC 6350
1298         * p.39</a>
1299         * @see <a href="http://tools.ietf.org/html/rfc2426#page-17">RFC 2426
1300         * p.17</a>
1301         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.17</a>
1302         */
1303        public void addTitle(Title title) {
1304                addProperty(title);
1305        }
1306
1307        /**
1308         * <p>
1309         * Adds a title associated with the person.
1310         * </p>
1311         * <p>
1312         * <b>Property name:</b> {@code TITLE}<br>
1313         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
1314         * </p>
1315         * @param title the title to add (e.g. "V.P. Research and Development")
1316         * @return the property object that was created
1317         * @see <a href="http://tools.ietf.org/html/rfc6350#page-39">RFC 6350
1318         * p.39</a>
1319         * @see <a href="http://tools.ietf.org/html/rfc2426#page-17">RFC 2426
1320         * p.17</a>
1321         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.17</a>
1322         */
1323        public Title addTitle(String title) {
1324                Title type = new Title(title);
1325                addTitle(type);
1326                return type;
1327        }
1328
1329        /**
1330         * <p>
1331         * Adds a title associated with the person.
1332         * </p>
1333         * <p>
1334         * <b>Property name:</b> {@code TITLE}<br>
1335         * <b>Supported versions:</b> {@code 4.0*}<br>
1336         * <i>* Only 4.0 supports alternative representations</i>
1337         * </p>
1338         * @param altRepresentations the alternative representations of the same
1339         * value. These properties contain the same information, but in different
1340         * forms (such as different languages). See {@link VCardParameters#getAltId
1341         * this description of the ALTID parameter} for more information. Note that
1342         * this method automatically assigns an appropriate ALTID parameter to each
1343         * property.
1344         * @see <a href="http://tools.ietf.org/html/rfc6350#page-39">RFC 6350
1345         * p.39</a>
1346         * @see <a href="http://tools.ietf.org/html/rfc2426#page-17">RFC 2426
1347         * p.17</a>
1348         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.17</a>
1349         */
1350        public void addTitleAlt(Title... altRepresentations) {
1351                addPropertyAlt(Title.class, altRepresentations);
1352        }
1353
1354        /**
1355         * <p>
1356         * Gets the roles associated with the person.
1357         * </p>
1358         * <p>
1359         * <b>Property name:</b> {@code ROLE}<br>
1360         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
1361         * </p>
1362         * @return the role properties (any changes made this list will affect the
1363         * {@link VCard} object and vice versa)
1364         * @see <a href="http://tools.ietf.org/html/rfc6350#page-39">RFC 6350
1365         * p.39</a>
1366         * @see <a href="http://tools.ietf.org/html/rfc2426#page-18">RFC 2426
1367         * p.18</a>
1368         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.17</a>
1369         */
1370        public List<Role> getRoles() {
1371                return getProperties(Role.class);
1372        }
1373
1374        /**
1375         * <p>
1376         * Adds a role associated with the person.
1377         * </p>
1378         * <p>
1379         * <b>Property name:</b> {@code ROLE}<br>
1380         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
1381         * </p>
1382         * @param role the role property to add
1383         * @see <a href="http://tools.ietf.org/html/rfc6350#page-39">RFC 6350
1384         * p.39</a>
1385         * @see <a href="http://tools.ietf.org/html/rfc2426#page-18">RFC 2426
1386         * p.18</a>
1387         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.17</a>
1388         */
1389        public void addRole(Role role) {
1390                addProperty(role);
1391        }
1392
1393        /**
1394         * <p>
1395         * Adds a role associated with the person.
1396         * </p>
1397         * <p>
1398         * <b>Property name:</b> {@code ROLE}<br>
1399         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
1400         * </p>
1401         * @param role the role to add (e.g. "Executive")
1402         * @return the property object that was created
1403         * @see <a href="http://tools.ietf.org/html/rfc6350#page-39">RFC 6350
1404         * p.39</a>
1405         * @see <a href="http://tools.ietf.org/html/rfc2426#page-18">RFC 2426
1406         * p.18</a>
1407         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.17</a>
1408         */
1409        public Role addRole(String role) {
1410                Role type = new Role(role);
1411                addRole(type);
1412                return type;
1413        }
1414
1415        /**
1416         * <p>
1417         * Adds a role associated with the person.
1418         * </p>
1419         * <p>
1420         * <b>Property name:</b> {@code ROLE}<br>
1421         * <b>Supported versions:</b> {@code 4.0*}<br>
1422         * <i>* Only 4.0 supports alternative representations</i>
1423         * </p>
1424         * @param altRepresentations the alternative representations of the same
1425         * value. These properties contain the same information, but in different
1426         * forms (such as different languages). See {@link VCardParameters#getAltId
1427         * this description of the ALTID parameter} for more information. Note that
1428         * this method automatically assigns an appropriate ALTID parameter to each
1429         * property.
1430         * @see <a href="http://tools.ietf.org/html/rfc6350#page-39">RFC 6350
1431         * p.39</a>
1432         * @see <a href="http://tools.ietf.org/html/rfc2426#page-18">RFC 2426
1433         * p.18</a>
1434         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.17</a>
1435         */
1436        public void addRoleAlt(Role... altRepresentations) {
1437                addPropertyAlt(Role.class, altRepresentations);
1438        }
1439
1440        /**
1441         * <p>
1442         * Gets the photos attached to the vCard, such as the person's portrait.
1443         * </p>
1444         * <p>
1445         * <b>Property name:</b> {@code PHOTO}<br>
1446         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
1447         * </p>
1448         * @return the photo properties (any changes made this list will affect the
1449         * {@link VCard} object and vice versa)
1450         * @see <a href="http://tools.ietf.org/html/rfc6350#page-30">RFC 6350
1451         * p.30</a>
1452         * @see <a href="http://tools.ietf.org/html/rfc2426#page-10">RFC 2426
1453         * p.10</a>
1454         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.10</a>
1455         */
1456        public List<Photo> getPhotos() {
1457                return getProperties(Photo.class);
1458        }
1459
1460        /**
1461         * <p>
1462         * Adds a photo to the vCard, such as the person's portrait.
1463         * </p>
1464         * <p>
1465         * <b>Property name:</b> {@code PHOTO}<br>
1466         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
1467         * </p>
1468         * @param photo the photo property to add
1469         * @see <a href="http://tools.ietf.org/html/rfc6350#page-30">RFC 6350
1470         * p.30</a>
1471         * @see <a href="http://tools.ietf.org/html/rfc2426#page-10">RFC 2426
1472         * p.10</a>
1473         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.10</a>
1474         */
1475        public void addPhoto(Photo photo) {
1476                addProperty(photo);
1477        }
1478
1479        /**
1480         * <p>
1481         * Adds a photo to the vCard, such as the person's portrait.
1482         * </p>
1483         * <p>
1484         * <b>Property name:</b> {@code PHOTO}<br>
1485         * <b>Supported versions:</b> {@code 4.0*}<br>
1486         * <i>* Only 4.0 supports alternative representations</i>
1487         * </p>
1488         * @param altRepresentations the alternative representations of the same
1489         * value. These properties contain the same information, but in different
1490         * forms (such as different languages). See {@link VCardParameters#getAltId
1491         * this description of the ALTID parameter} for more information. Note that
1492         * this method automatically assigns an appropriate ALTID parameter to each
1493         * property.
1494         * @see <a href="http://tools.ietf.org/html/rfc6350#page-30">RFC 6350
1495         * p.30</a>
1496         * @see <a href="http://tools.ietf.org/html/rfc2426#page-10">RFC 2426
1497         * p.10</a>
1498         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.10</a>
1499         */
1500        public void addPhotoAlt(Photo... altRepresentations) {
1501                addPropertyAlt(Photo.class, altRepresentations);
1502        }
1503
1504        /**
1505         * <p>
1506         * Gets the logos attached to the vCard, such a company logo.
1507         * </p>
1508         * <p>
1509         * <b>Property name:</b> {@code LOGO}<br>
1510         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
1511         * </p>
1512         * @return the logo properties (any changes made this list will affect the
1513         * {@link VCard} object and vice versa)
1514         * @see <a href="http://tools.ietf.org/html/rfc6350#page-40">RFC 6350
1515         * p.40</a>
1516         * @see <a href="http://tools.ietf.org/html/rfc2426#page-18">RFC 2426
1517         * p.18</a>
1518         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.17</a>
1519         */
1520        public List<Logo> getLogos() {
1521                return getProperties(Logo.class);
1522        }
1523
1524        /**
1525         * <p>
1526         * Adds a logo to the vCard, such as a company logo.
1527         * </p>
1528         * <p>
1529         * <b>Property name:</b> {@code LOGO}<br>
1530         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
1531         * </p>
1532         * @param logo the logo property to add
1533         * @see <a href="http://tools.ietf.org/html/rfc6350#page-40">RFC 6350
1534         * p.40</a>
1535         * @see <a href="http://tools.ietf.org/html/rfc2426#page-18">RFC 2426
1536         * p.18</a>
1537         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.17</a>
1538         */
1539        public void addLogo(Logo logo) {
1540                addProperty(logo);
1541        }
1542
1543        /**
1544         * <p>
1545         * Adds a logo to the vCard, such as a company logo.
1546         * </p>
1547         * <p>
1548         * <b>Property name:</b> {@code LOGO}<br>
1549         * <b>Supported versions:</b> {@code 4.0*}<br>
1550         * <i>* Only 4.0 supports alternative representations</i>
1551         * </p>
1552         * @param altRepresentations the alternative representations of the same
1553         * value. These properties contain the same information, but in different
1554         * forms (such as different languages). See {@link VCardParameters#getAltId
1555         * this description of the ALTID parameter} for more information. Note that
1556         * this method automatically assigns an appropriate ALTID parameter to each
1557         * property.
1558         * @see <a href="http://tools.ietf.org/html/rfc6350#page-40">RFC 6350
1559         * p.40</a>
1560         * @see <a href="http://tools.ietf.org/html/rfc2426#page-18">RFC 2426
1561         * p.18</a>
1562         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.17</a>
1563         */
1564        public void addLogoAlt(Logo... altRepresentations) {
1565                addPropertyAlt(Logo.class, altRepresentations);
1566        }
1567
1568        /**
1569         * <p>
1570         * Gets the sounds attached to the vCard, such as a pronunciation of the
1571         * person's name.
1572         * </p>
1573         * <p>
1574         * <b>Property name:</b> {@code SOUND}<br>
1575         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
1576         * </p>
1577         * @return the sound properties (any changes made this list will affect the
1578         * {@link VCard} object and vice versa)
1579         * @see <a href="http://tools.ietf.org/html/rfc6350#page-45">RFC 6350
1580         * p.45</a>
1581         * @see <a href="http://tools.ietf.org/html/rfc2426#page-23">RFC 2426
1582         * p.23</a>
1583         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.20</a>
1584         */
1585        public List<Sound> getSounds() {
1586                return getProperties(Sound.class);
1587        }
1588
1589        /**
1590         * <p>
1591         * Adds a sound to the vCard, such as a pronunciation of the person's name.
1592         * </p>
1593         * <p>
1594         * <b>Property name:</b> {@code SOUND}<br>
1595         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
1596         * </p>
1597         * @param sound the sound property to add
1598         * @see <a href="http://tools.ietf.org/html/rfc6350#page-45">RFC 6350
1599         * p.45</a>
1600         * @see <a href="http://tools.ietf.org/html/rfc2426#page-23">RFC 2426
1601         * p.23</a>
1602         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.20</a>
1603         */
1604        public void addSound(Sound sound) {
1605                addProperty(sound);
1606        }
1607
1608        /**
1609         * <p>
1610         * Adds a sound to the vCard, such as a pronunciation of the person's name.
1611         * </p>
1612         * <p>
1613         * <b>Property name:</b> {@code SOUND}<br>
1614         * <b>Supported versions:</b> {@code 4.0*}<br>
1615         * <i>* Only 4.0 supports alternative representations</i>
1616         * </p>
1617         * @param altRepresentations the alternative representations of the same
1618         * value. These properties contain the same information, but in different
1619         * forms (such as different languages). See {@link VCardParameters#getAltId
1620         * this description of the ALTID parameter} for more information. Note that
1621         * this method automatically assigns an appropriate ALTID parameter to each
1622         * property.
1623         * @see <a href="http://tools.ietf.org/html/rfc6350#page-45">RFC 6350
1624         * p.45</a>
1625         * @see <a href="http://tools.ietf.org/html/rfc2426#page-23">RFC 2426
1626         * p.23</a>
1627         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.20</a>
1628         */
1629        public void addSoundAlt(Sound... altRepresentations) {
1630                addPropertyAlt(Sound.class, altRepresentations);
1631        }
1632
1633        /**
1634         * <p>
1635         * Gets all {@link Birthplace} property instances.
1636         * </p>
1637         * <p>
1638         * There may be multiple instances if alternative representations are
1639         * defined (see {@link #setBirthplaceAlt(Birthplace...) setBirthplaceAlt}).
1640         * </p>
1641         * <p>
1642         * <b>Property name:</b> {@code BIRTHPLACE}<br>
1643         * <b>Supported versions:</b> {@code 4.0}
1644         * </p>
1645         * @return the birthplace properties (any changes made this list will affect
1646         * the {@link VCard} object and vice versa)
1647         * @see <a href="http://tools.ietf.org/html/rfc6474#page-2">RFC 6474 p.2</a>
1648         */
1649        public List<Birthplace> getBirthplaces() {
1650                return getProperties(Birthplace.class);
1651        }
1652
1653        /**
1654         * <p>
1655         * Gets the person's birthplace.
1656         * </p>
1657         * <p>
1658         * <b>Property name:</b> {@code BIRTHPLACE}<br>
1659         * <b>Supported versions:</b> {@code 4.0}
1660         * </p>
1661         * @return the first birthplace property or null if not set
1662         * @see <a href="http://tools.ietf.org/html/rfc6474#page-2">RFC 6474 p.2</a>
1663         */
1664        public Birthplace getBirthplace() {
1665                return getProperty(Birthplace.class);
1666        }
1667
1668        /**
1669         * <p>
1670         * Sets the person's birthplace.
1671         * </p>
1672         * <p>
1673         * <b>Property name:</b> {@code BIRTHPLACE}<br>
1674         * <b>Supported versions:</b> {@code 4.0}
1675         * </p>
1676         * @param altRepresentations the alternative representations of the same
1677         * value. These properties contain the same information, but in different
1678         * forms (such as different languages). See {@link VCardParameters#getAltId
1679         * this description of the ALTID parameter} for more information. Note that
1680         * this method automatically assigns an appropriate ALTID parameter to each
1681         * property.
1682         * @see <a href="http://tools.ietf.org/html/rfc6474#page-2">RFC 6474 p.2</a>
1683         */
1684        public void setBirthplaceAlt(Birthplace... altRepresentations) {
1685                setPropertyAlt(Birthplace.class, altRepresentations);
1686        }
1687
1688        /**
1689         * <p>
1690         * Sets the person's birthplace.
1691         * </p>
1692         * <p>
1693         * <b>Property name:</b> {@code BIRTHPLACE}<br>
1694         * <b>Supported versions:</b> {@code 4.0}
1695         * </p>
1696         * @param birthplace the birthplace property or null to remove
1697         * @see <a href="http://tools.ietf.org/html/rfc6474#page-2">RFC 6474 p.2</a>
1698         */
1699        public void setBirthplace(Birthplace birthplace) {
1700                setProperty(Birthplace.class, birthplace);
1701        }
1702
1703        /**
1704         * <p>
1705         * Gets all {@link Deathplace} property instances.
1706         * </p>
1707         * <p>
1708         * There may be multiple instances if alternative representations are
1709         * defined (see {@link #setDeathplaceAlt(Deathplace...) setDeathplaceAlt}).
1710         * </p>
1711         * <p>
1712         * <b>Property name:</b> {@code DEATHPLACE}<br>
1713         * <b>Supported versions:</b> {@code 4.0}
1714         * </p>
1715         * @return the deathplace properties (any changes made this list will affect
1716         * the {@link VCard} object and vice versa)
1717         * @see <a href="http://tools.ietf.org/html/rfc6474#page-3">RFC 6474 p.3</a>
1718         */
1719        public List<Deathplace> getDeathplaces() {
1720                return getProperties(Deathplace.class);
1721        }
1722
1723        /**
1724         * <p>
1725         * Gets the person's place of death.
1726         * </p>
1727         * <p>
1728         * <b>Property name:</b> {@code DEATHPLACE}<br>
1729         * <b>Supported versions:</b> {@code 4.0}
1730         * </p>
1731         * @return the first deathplace property or null if not set
1732         * @see <a href="http://tools.ietf.org/html/rfc6474#page-3">RFC 6474 p.3</a>
1733         */
1734        public Deathplace getDeathplace() {
1735                return getProperty(Deathplace.class);
1736        }
1737
1738        /**
1739         * <p>
1740         * Sets the person's place of death.
1741         * </p>
1742         * <p>
1743         * <b>Property name:</b> {@code DEATHPLACE}<br>
1744         * <b>Supported versions:</b> {@code 4.0}
1745         * </p>
1746         * @param altRepresentations the alternative representations of the same
1747         * value. These properties contain the same information, but in different
1748         * forms (such as different languages). See {@link VCardParameters#getAltId
1749         * this description of the ALTID parameter} for more information. Note that
1750         * this method automatically assigns an appropriate ALTID parameter to each
1751         * property.
1752         * @see <a href="http://tools.ietf.org/html/rfc6474#page-3">RFC 6474 p.3</a>
1753         */
1754        public void setDeathplaceAlt(Deathplace... altRepresentations) {
1755                setPropertyAlt(Deathplace.class, altRepresentations);
1756        }
1757
1758        /**
1759         * <p>
1760         * Sets the person's place of death.
1761         * </p>
1762         * <p>
1763         * <b>Property name:</b> {@code DEATHPLACE}<br>
1764         * <b>Supported versions:</b> {@code 4.0}
1765         * </p>
1766         * @param deathplace the deathplace property or null to remove
1767         * @see <a href="http://tools.ietf.org/html/rfc6474#page-3">RFC 6474 p.3</a>
1768         */
1769        public void setDeathplace(Deathplace deathplace) {
1770                setProperty(Deathplace.class, deathplace);
1771        }
1772
1773        /**
1774         * <p>
1775         * Gets all {@link Deathdate} property instances.
1776         * </p>
1777         * <p>
1778         * There may be multiple instances if alternative representations are
1779         * defined (see {@link #setDeathdateAlt(Deathdate...) setDeathdateAlt}).
1780         * </p>
1781         * <p>
1782         * <b>Property name:</b> {@code DEATHDATE}<br>
1783         * <b>Supported versions:</b> {@code 4.0}
1784         * </p>
1785         * @return the death date properties (any changes made this list will affect
1786         * the {@link VCard} object and vice versa)
1787         * @see <a href="http://tools.ietf.org/html/rfc6474#page-4">RFC 6474 p.4</a>
1788         */
1789        public List<Deathdate> getDeathdates() {
1790                return getProperties(Deathdate.class);
1791        }
1792
1793        /**
1794         * <p>
1795         * Gets the person's time of death.
1796         * </p>
1797         * <p>
1798         * <b>Property name:</b> {@code DEATHDATE}<br>
1799         * <b>Supported versions:</b> {@code 4.0}
1800         * </p>
1801         * @return the first death date property or null if not set
1802         * @see <a href="http://tools.ietf.org/html/rfc6474">RFC 6474</a>
1803         * @see <a href="http://tools.ietf.org/html/rfc6474#page-4">RFC 6474 p.4</a>
1804         */
1805        public Deathdate getDeathdate() {
1806                return getProperty(Deathdate.class);
1807        }
1808
1809        /**
1810         * <p>
1811         * Sets the person's time of death.
1812         * </p>
1813         * <p>
1814         * <b>Property name:</b> {@code DEATHDATE}<br>
1815         * <b>Supported versions:</b> {@code 4.0}
1816         * </p>
1817         * @param altRepresentations the alternative representations of the same
1818         * value. These properties contain the same information, but in different
1819         * forms (such as different languages). See {@link VCardParameters#getAltId
1820         * this description of the ALTID parameter} for more information. Note that
1821         * this method automatically assigns an appropriate ALTID parameter to each
1822         * property.
1823         * @see <a href="http://tools.ietf.org/html/rfc6474#page-4">RFC 6474 p.4</a>
1824         */
1825        public void setDeathdateAlt(Deathdate... altRepresentations) {
1826                setPropertyAlt(Deathdate.class, altRepresentations);
1827        }
1828
1829        /**
1830         * <p>
1831         * Sets the person's time of death.
1832         * </p>
1833         * <p>
1834         * <b>Property name:</b> {@code DEATHDATE}<br>
1835         * <b>Supported versions:</b> {@code 4.0}
1836         * </p>
1837         * @param deathdate the death date property or null to remove
1838         * @see <a href="http://tools.ietf.org/html/rfc6474">RFC 6474</a>
1839         * @see <a href="http://tools.ietf.org/html/rfc6474#page-4">RFC 6474 p.4</a>
1840         */
1841        public void setDeathdate(Deathdate deathdate) {
1842                setProperty(Deathdate.class, deathdate);
1843        }
1844
1845        /**
1846         * <p>
1847         * Gets all {@link Birthday} property instances.
1848         * </p>
1849         * <p>
1850         * There may be multiple instances if alternative representations are
1851         * defined (see {@link #setBirthdayAlt(Birthday...) setBirthdayAlt}).
1852         * </p>
1853         * <p>
1854         * <b>Property name:</b> {@code BDAY}<br>
1855         * <b>Supported versions:</b> {@code 4.0*}<br>
1856         * <i>* Only 4.0 supports alternative representations</i>
1857         * </p>
1858         * @return the birthday properties (any changes made this list will affect
1859         * the {@link VCard} object and vice versa)
1860         * @see <a href="http://tools.ietf.org/html/rfc6350#page-30">RFC 6350
1861         * p.30</a>
1862         * @see <a href="http://tools.ietf.org/html/rfc2426#page-11">RFC 2426
1863         * p.11</a>
1864         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.11</a>
1865         */
1866        public List<Birthday> getBirthdays() {
1867                return getProperties(Birthday.class);
1868        }
1869
1870        /**
1871         * <p>
1872         * Gets the person's birthday.
1873         * </p>
1874         * <p>
1875         * <b>Property name:</b> {@code BDAY}<br>
1876         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
1877         * </p>
1878         * @return the first birthday property or null if not set
1879         * @see <a href="http://tools.ietf.org/html/rfc6350#page-30">RFC 6350
1880         * p.30</a>
1881         * @see <a href="http://tools.ietf.org/html/rfc2426#page-11">RFC 2426
1882         * p.11</a>
1883         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.11</a>
1884         */
1885        public Birthday getBirthday() {
1886                return getProperty(Birthday.class);
1887        }
1888
1889        /**
1890         * <p>
1891         * Sets the person's birthday.
1892         * </p>
1893         * <p>
1894         * <b>Property name:</b> {@code BDAY}<br>
1895         * <b>Supported versions:</b> {@code 4.0*}<br>
1896         * <i>* Only 4.0 supports alternative representations</i>
1897         * </p>
1898         * @param altRepresentations the alternative representations of the same
1899         * value. These properties contain the same information, but in different
1900         * forms (such as different languages). See {@link VCardParameters#getAltId
1901         * this description of the ALTID parameter} for more information. Note that
1902         * this method automatically assigns an appropriate ALTID parameter to each
1903         * property.
1904         * @see <a href="http://tools.ietf.org/html/rfc6350#page-30">RFC 6350
1905         * p.30</a>
1906         * @see <a href="http://tools.ietf.org/html/rfc2426#page-11">RFC 2426
1907         * p.11</a>
1908         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.11</a>
1909         */
1910        public void setBirthdayAlt(Birthday... altRepresentations) {
1911                setPropertyAlt(Birthday.class, altRepresentations);
1912        }
1913
1914        /**
1915         * <p>
1916         * Sets the person's birthday.
1917         * </p>
1918         * <p>
1919         * <b>Property name:</b> {@code BDAY}<br>
1920         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
1921         * </p>
1922         * @param birthday the birthday or null to remove
1923         * @see <a href="http://tools.ietf.org/html/rfc6350#page-30">RFC 6350
1924         * p.30</a>
1925         * @see <a href="http://tools.ietf.org/html/rfc2426#page-11">RFC 2426
1926         * p.11</a>
1927         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.11</a>
1928         */
1929        public void setBirthday(Birthday birthday) {
1930                setProperty(Birthday.class, birthday);
1931        }
1932
1933        /**
1934         * <p>
1935         * Gets all {@link Anniversary} property instances.
1936         * </p>
1937         * <p>
1938         * There may be multiple instances if alternative representations are
1939         * defined (see {@link #setAnniversaryAlt(Anniversary...) setAnniversaryAlt}
1940         * ).
1941         * </p>
1942         * <p>
1943         * <b>Property name:</b> {@code ANNIVERSARY}<br>
1944         * <b>Supported versions:</b> {@code 4.0}
1945         * </p>
1946         * @return the anniversary properties (any changes made this list will
1947         * affect the {@link VCard} object and vice versa)
1948         * @see <a href="http://tools.ietf.org/html/rfc6350#page-31">RFC 6350
1949         * p.31</a>
1950         */
1951        public List<Anniversary> getAnniversaries() {
1952                return getProperties(Anniversary.class);
1953        }
1954
1955        /**
1956         * <p>
1957         * Gets the person's anniversary.
1958         * </p>
1959         * <p>
1960         * <b>Property name:</b> {@code ANNIVERSARY}<br>
1961         * <b>Supported versions:</b> {@code 4.0}
1962         * </p>
1963         * @return the first anniversary property or null if not set
1964         * @see <a href="http://tools.ietf.org/html/rfc6350#page-31">RFC 6350
1965         * p.31</a>
1966         */
1967        public Anniversary getAnniversary() {
1968                return getProperty(Anniversary.class);
1969        }
1970
1971        /**
1972         * <p>
1973         * Sets the person's anniversary.
1974         * </p>
1975         * <p>
1976         * <b>Property name:</b> {@code ANNIVERSARY}<br>
1977         * <b>Supported versions:</b> {@code 4.0}
1978         * </p>
1979         * @param altRepresentations the alternative representations of the same
1980         * value. These properties contain the same information, but in different
1981         * forms (such as different languages). See {@link VCardParameters#getAltId
1982         * this description of the ALTID parameter} for more information. Note that
1983         * this method automatically assigns an appropriate ALTID parameter to each
1984         * property.
1985         * @see <a href="http://tools.ietf.org/html/rfc6350#page-31">RFC 6350
1986         * p.31</a>
1987         */
1988        public void setAnniversaryAlt(Anniversary... altRepresentations) {
1989                setPropertyAlt(Anniversary.class, altRepresentations);
1990        }
1991
1992        /**
1993         * <p>
1994         * Sets the person's anniversary.
1995         * </p>
1996         * <p>
1997         * <b>Property name:</b> {@code ANNIVERSARY}<br>
1998         * <b>Supported versions:</b> {@code 4.0}
1999         * </p>
2000         * @param anniversary the anniversary property or null to remove
2001         * @see <a href="http://tools.ietf.org/html/rfc6350#page-31">RFC 6350
2002         * p.31</a>
2003         */
2004        public void setAnniversary(Anniversary anniversary) {
2005                setProperty(Anniversary.class, anniversary);
2006        }
2007
2008        /**
2009         * Gets the time that the vCard was last modified.
2010         * <p>
2011         * <b>Property name:</b> {@code REV}<br>
2012         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
2013         * </p>
2014         * @return the revision property or null if not set
2015         * @see <a href="http://tools.ietf.org/html/rfc6350#page-45">RFC 6350
2016         * p.45</a>
2017         * @see <a href="http://tools.ietf.org/html/rfc2426#page-22">RFC 2426
2018         * p.22</a>
2019         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.19</a>
2020         */
2021        public Revision getRevision() {
2022                return getProperty(Revision.class);
2023        }
2024
2025        /**
2026         * <p>
2027         * Sets the time that the vCard was last modified.
2028         * </p>
2029         * <p>
2030         * <b>Property name:</b> {@code REV}<br>
2031         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
2032         * </p>
2033         * @param revision the revision property or null to remove
2034         * @see <a href="http://tools.ietf.org/html/rfc6350#page-45">RFC 6350
2035         * p.45</a>
2036         * @see <a href="http://tools.ietf.org/html/rfc2426#page-22">RFC 2426
2037         * p.22</a>
2038         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.19</a>
2039         */
2040        public void setRevision(Revision revision) {
2041                setProperty(Revision.class, revision);
2042        }
2043
2044        /**
2045         * <p>
2046         * Sets the time that the vCard was last modified.
2047         * </p>
2048         * <p>
2049         * <b>Property name:</b> {@code REV}<br>
2050         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
2051         * </p>
2052         * @param rev the last modified time or null to remove
2053         * @return the property object that was created
2054         * @see <a href="http://tools.ietf.org/html/rfc6350#page-45">RFC 6350
2055         * p.45</a>
2056         * @see <a href="http://tools.ietf.org/html/rfc2426#page-22">RFC 2426
2057         * p.22</a>
2058         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.19</a>
2059         */
2060        public Revision setRevision(Date rev) {
2061                Revision type = (rev == null) ? null : new Revision(rev);
2062                setRevision(type);
2063                return type;
2064        }
2065
2066        /**
2067         * <p>
2068         * Gets the product ID, which identifies the software that created the
2069         * vCard.
2070         * </p>
2071         * <p>
2072         * <b>Property name:</b> {@code PRODID}<br>
2073         * <b>Supported versions:</b> {@code 3.0, 4.0}
2074         * </p>
2075         * @return the product ID property or null if not set
2076         * @see <a href="http://tools.ietf.org/html/rfc6350#page-44">RFC 6350
2077         * p.44</a>
2078         * @see <a href="http://tools.ietf.org/html/rfc2426#page-21">RFC 2426
2079         * p.21</a>
2080         */
2081        public ProductId getProductId() {
2082                return getProperty(ProductId.class);
2083        }
2084
2085        /**
2086         * <p>
2087         * Sets the product ID, which identifies the software that created the
2088         * vCard.
2089         * </p>
2090         * <p>
2091         * <b>Property name:</b> {@code PRODID}<br>
2092         * <b>Supported versions:</b> {@code 3.0, 4.0}
2093         * </p>
2094         * @param productId the product ID property or null to remove
2095         * @see <a href="http://tools.ietf.org/html/rfc6350#page-44">RFC 6350
2096         * p.44</a>
2097         * @see <a href="http://tools.ietf.org/html/rfc2426#page-21">RFC 2426
2098         * p.21</a>
2099         */
2100        public void setProductId(ProductId productId) {
2101                setProperty(ProductId.class, productId);
2102        }
2103
2104        /**
2105         * <p>
2106         * Sets the product ID, which identifies the software that created the
2107         * vCard.
2108         * </p>
2109         * <p>
2110         * <b>Property name:</b> {@code PRODID}<br>
2111         * <b>Supported versions:</b> {@code 3.0, 4.0}
2112         * </p>
2113         * @param productId the product ID (e.g. "ez-vcard 1.0") or null to remove
2114         * @return the property object that was created
2115         * @see <a href="http://tools.ietf.org/html/rfc6350#page-44">RFC 6350
2116         * p.44</a>
2117         * @see <a href="http://tools.ietf.org/html/rfc2426#page-21">RFC 2426
2118         * p.21</a>
2119         */
2120        public ProductId setProductId(String productId) {
2121                ProductId type = (productId == null) ? null : new ProductId(productId);
2122                setProductId(type);
2123                return type;
2124        }
2125
2126        /**
2127         * <p>
2128         * Gets the mailing addresses.
2129         * </p>
2130         * <p>
2131         * <b>Property name:</b> {@code ADR}<br>
2132         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
2133         * </p>
2134         * @return the mailing address properties (any changes made this list will
2135         * affect the {@link VCard} object and vice versa)
2136         * @see <a href="http://tools.ietf.org/html/rfc6350#page-32">RFC 6350
2137         * p.32</a>
2138         * @see <a href="http://tools.ietf.org/html/rfc2426#page-11">RFC 2426
2139         * p.11</a>
2140         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.11</a>
2141         */
2142        public List<Address> getAddresses() {
2143                return getProperties(Address.class);
2144        }
2145
2146        /**
2147         * <p>
2148         * Adds a mailing address.
2149         * </p>
2150         * <p>
2151         * <b>Property name:</b> {@code ADR}<br>
2152         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
2153         * </p>
2154         * @param address the mailing address property to add
2155         * @see <a href="http://tools.ietf.org/html/rfc6350#page-32">RFC 6350
2156         * p.32</a>
2157         * @see <a href="http://tools.ietf.org/html/rfc2426#page-11">RFC 2426
2158         * p.11</a>
2159         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.11</a>
2160         */
2161        public void addAddress(Address address) {
2162                addProperty(address);
2163        }
2164
2165        /**
2166         * <p>
2167         * Adds a mailing address.
2168         * </p>
2169         * <p>
2170         * <b>Property name:</b> {@code ADR}<br>
2171         * <b>Supported versions:</b> {@code 4.0*}<br>
2172         * <i>* Only 4.0 supports alternative representations</i>
2173         * </p>
2174         * @param altRepresentations the alternative representations of the same
2175         * value. These properties contain the same information, but in different
2176         * forms (such as different languages). See {@link VCardParameters#getAltId
2177         * this description of the ALTID parameter} for more information. Note that
2178         * this method automatically assigns an appropriate ALTID parameter to each
2179         * property.
2180         * @see <a href="http://tools.ietf.org/html/rfc6350#page-32">RFC 6350
2181         * p.32</a>
2182         * @see <a href="http://tools.ietf.org/html/rfc2426#page-11">RFC 2426
2183         * p.11</a>
2184         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.11</a>
2185         */
2186        public void addAddressAlt(Address... altRepresentations) {
2187                addPropertyAlt(Address.class, altRepresentations);
2188        }
2189
2190        /**
2191         * <p>
2192         * Gets all mailing labels that could not be assigned to an {@link Address}
2193         * property. Use {@link Address#getLabel} to get a label that has been
2194         * assigned to an address.
2195         * </p>
2196         * <p>
2197         * <b>Property name:</b> {@code LABEL}<br>
2198         * <b>Supported versions:</b> {@code 2.1, 3.0}
2199         * </p>
2200         * @return the orphaned label properties (any changes made this list will
2201         * affect the {@link VCard} object and vice versa)
2202         * @see <a href="http://tools.ietf.org/html/rfc2426#page-13">RFC 2426
2203         * p.13</a>
2204         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.12</a>
2205         */
2206        public List<Label> getOrphanedLabels() {
2207                return getProperties(Label.class);
2208        }
2209
2210        /**
2211         * <p>
2212         * Adds a mailing label which is not associated with an {@link Address}
2213         * property.
2214         * </p>
2215         * <p>
2216         * Use of this method is strongly discouraged. To add a mailing label to an
2217         * address, use the {@link Address#setLabel} method.
2218         * </p>
2219         * <p>
2220         * <b>Property name:</b> {@code LABEL}<br>
2221         * <b>Supported versions:</b> {@code 2.1, 3.0}
2222         * </p>
2223         * @param label the orphaned label property to add
2224         * @see <a href="http://tools.ietf.org/html/rfc2426#page-13">RFC 2426
2225         * p.13</a>
2226         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.12</a>
2227         */
2228        public void addOrphanedLabel(Label label) {
2229                addProperty(label);
2230        }
2231
2232        /**
2233         * <p>
2234         * Gets the email addresses.
2235         * </p>
2236         * <p>
2237         * <b>Property name:</b> {@code EMAIL}<br>
2238         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
2239         * </p>
2240         * @return the email address properties (any changes made this list will
2241         * affect the {@link VCard} object and vice versa)
2242         * @see <a href="http://tools.ietf.org/html/rfc6350#page-36">RFC 6350
2243         * p.36</a>
2244         * @see <a href="http://tools.ietf.org/html/rfc2426#page-15">RFC 2426
2245         * p.15</a>
2246         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.15</a>
2247         */
2248        public List<Email> getEmails() {
2249                return getProperties(Email.class);
2250        }
2251
2252        /**
2253         * <p>
2254         * Adds an email address.
2255         * </p>
2256         * <p>
2257         * <b>Property name:</b> {@code EMAIL}<br>
2258         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
2259         * </p>
2260         * @param email the email address property to add
2261         * @see <a href="http://tools.ietf.org/html/rfc6350#page-36">RFC 6350
2262         * p.36</a>
2263         * @see <a href="http://tools.ietf.org/html/rfc2426#page-15">RFC 2426
2264         * p.15</a>
2265         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.15</a>
2266         */
2267        public void addEmail(Email email) {
2268                addProperty(email);
2269        }
2270
2271        /**
2272         * <p>
2273         * Adds an email address.
2274         * </p>
2275         * <p>
2276         * <b>Property name:</b> {@code EMAIL}<br>
2277         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
2278         * </p>
2279         * @param email the email address to add (e.g. "johndoe@aol.com")
2280         * @param types the type(s) to assign to the email
2281         * @return the property object that was created
2282         * @see <a href="http://tools.ietf.org/html/rfc6350#page-36">RFC 6350
2283         * p.36</a>
2284         * @see <a href="http://tools.ietf.org/html/rfc2426#page-15">RFC 2426
2285         * p.15</a>
2286         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.15</a>
2287         */
2288        public Email addEmail(String email, EmailType... types) {
2289                Email property = new Email(email);
2290                property.getTypes().addAll(Arrays.asList(types));
2291                addEmail(property);
2292                return property;
2293        }
2294
2295        /**
2296         * <p>
2297         * Adds an email address.
2298         * </p>
2299         * <p>
2300         * <b>Property name:</b> {@code EMAIL}<br>
2301         * <b>Supported versions:</b> {@code 4.0*}<br>
2302         * <i>* Only 4.0 supports alternative representations</i>
2303         * </p>
2304         * @param altRepresentations the alternative representations of the same
2305         * value. These properties contain the same information, but in different
2306         * forms (such as different languages). See {@link VCardParameters#getAltId
2307         * this description of the ALTID parameter} for more information. Note that
2308         * this method automatically assigns an appropriate ALTID parameter to each
2309         * property.
2310         * @see <a href="http://tools.ietf.org/html/rfc6350#page-36">RFC 6350
2311         * p.36</a>
2312         * @see <a href="http://tools.ietf.org/html/rfc2426#page-15">RFC 2426
2313         * p.15</a>
2314         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.15</a>
2315         */
2316        public void addEmailAlt(Email... altRepresentations) {
2317                addPropertyAlt(Email.class, altRepresentations);
2318        }
2319
2320        /**
2321         * <p>
2322         * Gets the telephone numbers.
2323         * </p>
2324         * <p>
2325         * <b>Property name:</b> {@code TEL}<br>
2326         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
2327         * </p>
2328         * @return the telephone number properties (any changes made this list will
2329         * affect the {@link VCard} object and vice versa)
2330         * @see <a href="http://tools.ietf.org/html/rfc6350#page-34">RFC 6350
2331         * p.34</a>
2332         * @see <a href="http://tools.ietf.org/html/rfc2426#page-14">RFC 2426
2333         * p.14</a>
2334         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.13</a>
2335         */
2336        public List<Telephone> getTelephoneNumbers() {
2337                return getProperties(Telephone.class);
2338        }
2339
2340        /**
2341         * <p>
2342         * Adds a telephone number.
2343         * </p>
2344         * <p>
2345         * <b>Property name:</b> {@code TEL}<br>
2346         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
2347         * </p>
2348         * @param telephoneNumber the telephone number property to add
2349         * @see <a href="http://tools.ietf.org/html/rfc6350#page-34">RFC 6350
2350         * p.34</a>
2351         * @see <a href="http://tools.ietf.org/html/rfc2426#page-14">RFC 2426
2352         * p.14</a>
2353         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.13</a>
2354         */
2355        public void addTelephoneNumber(Telephone telephoneNumber) {
2356                addProperty(telephoneNumber);
2357        }
2358
2359        /**
2360         * <p>
2361         * Adds a telephone number.
2362         * </p>
2363         * <p>
2364         * <b>Property name:</b> {@code TEL}<br>
2365         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
2366         * </p>
2367         * @param telephoneNumber the telephone number to add (e.g.
2368         * "+1 555-555-5555")
2369         * @param types the type(s) to assign to the telephone number (e.g. "cell",
2370         * "work", etc)
2371         * @return the property object that was created
2372         * @see <a href="http://tools.ietf.org/html/rfc6350#page-34">RFC 6350
2373         * p.34</a>
2374         * @see <a href="http://tools.ietf.org/html/rfc2426#page-14">RFC 2426
2375         * p.14</a>
2376         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.13</a>
2377         */
2378        public Telephone addTelephoneNumber(String telephoneNumber, TelephoneType... types) {
2379                Telephone property = new Telephone(telephoneNumber);
2380                property.getTypes().addAll(Arrays.asList(types));
2381                addTelephoneNumber(property);
2382                return property;
2383        }
2384
2385        /**
2386         * <p>
2387         * Adds a telephone number.
2388         * </p>
2389         * <p>
2390         * <b>Property name:</b> {@code TEL}<br>
2391         * <b>Supported versions:</b> {@code 4.0*}<br>
2392         * <i>* Only 4.0 supports alternative representations</i>
2393         * </p>
2394         * @param altRepresentations the alternative representations of the same
2395         * value. These properties contain the same information, but in different
2396         * forms (such as different languages). See {@link VCardParameters#getAltId
2397         * this description of the ALTID parameter} for more information. Note that
2398         * this method automatically assigns an appropriate ALTID parameter to each
2399         * property.
2400         * @see <a href="http://tools.ietf.org/html/rfc6350#page-34">RFC 6350
2401         * p.34</a>
2402         * @see <a href="http://tools.ietf.org/html/rfc2426#page-14">RFC 2426
2403         * p.14</a>
2404         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.13</a>
2405         */
2406        public void addTelephoneNumberAlt(Telephone... altRepresentations) {
2407                addPropertyAlt(Telephone.class, altRepresentations);
2408        }
2409
2410        /**
2411         * <p>
2412         * Gets the email client that the person uses.
2413         * </p>
2414         * <p>
2415         * <b>Property name:</b> {@code MAILER}<br>
2416         * <b>Supported versions:</b> {@code 2.1, 3.0}
2417         * </p>
2418         * @return the mailer property or null if not set
2419         * @see <a href="http://tools.ietf.org/html/rfc2426#page-15">RFC 2426
2420         * p.15</a>
2421         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.15</a>
2422         */
2423        public Mailer getMailer() {
2424                return getProperty(Mailer.class);
2425        }
2426
2427        /**
2428         * <p>
2429         * Sets the email client that the person uses.
2430         * </p>
2431         * <p>
2432         * <b>Property name:</b> {@code MAILER}<br>
2433         * <b>Supported versions:</b> {@code 2.1, 3.0}
2434         * </p>
2435         * @param mailer the mailer property or null to remove
2436         * @see <a href="http://tools.ietf.org/html/rfc2426#page-15">RFC 2426
2437         * p.15</a>
2438         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.15</a>
2439         */
2440        public void setMailer(Mailer mailer) {
2441                setProperty(Mailer.class, mailer);
2442        }
2443
2444        /**
2445         * <p>
2446         * Sets the email client that the person uses.
2447         * </p>
2448         * <p>
2449         * <b>Property name:</b> {@code MAILER}<br>
2450         * <b>Supported versions:</b> {@code 2.1, 3.0}
2451         * </p>
2452         * @param mailer the email client (e.g. "Thunderbird") or null to remove
2453         * @return the property object that was created
2454         * @see <a href="http://tools.ietf.org/html/rfc2426#page-15">RFC 2426
2455         * p.15</a>
2456         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.15</a>
2457         */
2458        public Mailer setMailer(String mailer) {
2459                Mailer type = (mailer == null) ? null : new Mailer(mailer);
2460                setMailer(type);
2461                return type;
2462        }
2463
2464        /**
2465         * <p>
2466         * Gets the URLs. URLs can point to websites such as a personal homepage or
2467         * business website.
2468         * </p>
2469         * <p>
2470         * <b>Property name:</b> {@code URL}<br>
2471         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
2472         * </p>
2473         * @return the URL properties (any changes made this list will affect the
2474         * {@link VCard} object and vice versa)
2475         * @see <a href="http://tools.ietf.org/html/rfc6350#page-47">RFC 6350
2476         * p.47</a>
2477         * @see <a href="http://tools.ietf.org/html/rfc2426#page-25">RFC 2426
2478         * p.25</a>
2479         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.21</a>
2480         */
2481        public List<Url> getUrls() {
2482                return getProperties(Url.class);
2483        }
2484
2485        /**
2486         * <p>
2487         * Adds a URL. URLs can point to websites such as a personal homepage or
2488         * business website.
2489         * </p>
2490         * <p>
2491         * <b>Property name:</b> {@code URL}<br>
2492         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
2493         * </p>
2494         * @param url the URL property to add
2495         * @see <a href="http://tools.ietf.org/html/rfc6350#page-47">RFC 6350
2496         * p.47</a>
2497         * @see <a href="http://tools.ietf.org/html/rfc2426#page-25">RFC 2426
2498         * p.25</a>
2499         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.21</a>
2500         */
2501        public void addUrl(Url url) {
2502                addProperty(url);
2503        }
2504
2505        /**
2506         * <p>
2507         * Adds a URL. URLs can point to websites such as a personal homepage or
2508         * business website.
2509         * </p>
2510         * <p>
2511         * <b>Property name:</b> {@code URL}<br>
2512         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
2513         * </p>
2514         * @param url the URL to add (e.g. "http://example.com")
2515         * @return the property object that was created
2516         * @see <a href="http://tools.ietf.org/html/rfc6350#page-47">RFC 6350
2517         * p.47</a>
2518         * @see <a href="http://tools.ietf.org/html/rfc2426#page-25">RFC 2426
2519         * p.25</a>
2520         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.21</a>
2521         */
2522        public Url addUrl(String url) {
2523                Url type = new Url(url);
2524                addUrl(type);
2525                return type;
2526        }
2527
2528        /**
2529         * <p>
2530         * Adds a URL. URLs can point to websites such as a personal homepage or
2531         * business website.
2532         * </p>
2533         * <p>
2534         * <b>Property name:</b> {@code URL}<br>
2535         * <b>Supported versions:</b> {@code 4.0*}<br>
2536         * <i>* Only 4.0 supports alternative representations</i>
2537         * </p>
2538         * @param altRepresentations the alternative representations of the same
2539         * value. These properties contain the same information, but in different
2540         * forms (such as different languages). See {@link VCardParameters#getAltId
2541         * this description of the ALTID parameter} for more information. Note that
2542         * this method automatically assigns an appropriate ALTID parameter to each
2543         * property.
2544         * @see <a href="http://tools.ietf.org/html/rfc6350#page-47">RFC 6350
2545         * p.47</a>
2546         * @see <a href="http://tools.ietf.org/html/rfc2426#page-25">RFC 2426
2547         * p.25</a>
2548         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.21</a>
2549         */
2550        public void addUrlAlt(Url... altRepresentations) {
2551                addPropertyAlt(Url.class, altRepresentations);
2552        }
2553
2554        /**
2555         * <p>
2556         * Gets all instances of the {@link Timezone} property.
2557         * </p>
2558         * <p>
2559         * Version 4.0 vCards may have multiple instances if alternative
2560         * representations are defined (see {@link #setTimezoneAlt(Timezone...)
2561         * setTimezoneAlt}) or if properties with different TYPE parameters are
2562         * defined.
2563         * </p>
2564         * <p>
2565         * <b>Property name:</b> {@code TZ}<br>
2566         * <b>Supported versions:</b> {@code 4.0*}<br>
2567         * <i>* Only 4.0 supports multiple instances</i>
2568         * </p>
2569         * @return the timezone properties (any changes made this list will affect
2570         * the {@link VCard} object and vice versa)
2571         * @see <a href="http://tools.ietf.org/html/rfc6350#page-22">RFC 6350
2572         * p.22</a>
2573         * @see <a href="http://tools.ietf.org/html/rfc2426#page-16">RFC 2426
2574         * p.16</a>
2575         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.16</a>
2576         */
2577        public List<Timezone> getTimezones() {
2578                return getProperties(Timezone.class);
2579        }
2580
2581        /**
2582         * <p>
2583         * Gets the timezone the person lives/works in.
2584         * </p>
2585         * <p>
2586         * <b>Property name:</b> {@code TZ}<br>
2587         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
2588         * </p>
2589         * @return the first timezone property or null if not set
2590         * @see <a href="http://tools.ietf.org/html/rfc6350#page-22">RFC 6350
2591         * p.22</a>
2592         * @see <a href="http://tools.ietf.org/html/rfc2426#page-16">RFC 2426
2593         * p.16</a>
2594         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.16</a>
2595         */
2596        public Timezone getTimezone() {
2597                return getProperty(Timezone.class);
2598        }
2599
2600        /**
2601         * <p>
2602         * Sets the timezone the person lives/works in.
2603         * </p>
2604         * <p>
2605         * <b>Property name:</b> {@code TZ}<br>
2606         * <b>Supported versions:</b> {@code 4.0*}<br>
2607         * <i>* Only 4.0 supports alternative representations</i>
2608         * </p>
2609         * @param altRepresentations the alternative representations of the same
2610         * value. These properties contain the same information, but in different
2611         * forms (such as different languages). See {@link VCardParameters#getAltId
2612         * this description of the ALTID parameter} for more information. Note that
2613         * this method automatically assigns an appropriate ALTID parameter to each
2614         * property.
2615         * @see <a href="http://tools.ietf.org/html/rfc6350#page-22">RFC 6350
2616         * p.22</a>
2617         * @see <a href="http://tools.ietf.org/html/rfc2426#page-16">RFC 2426
2618         * p.16</a>
2619         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.16</a>
2620         */
2621        public void setTimezoneAlt(Timezone... altRepresentations) {
2622                setPropertyAlt(Timezone.class, altRepresentations);
2623        }
2624
2625        /**
2626         * <p>
2627         * Adds a timezone the person lives/works in.
2628         * </p>
2629         * <p>
2630         * <b>Property name:</b> {@code TZ}<br>
2631         * <b>Supported versions:</b> {@code 4.0*}<br>
2632         * <i>* Only 4.0 supports alternative representations</i>
2633         * </p>
2634         * @param altRepresentations the alternative representations of the same
2635         * value. These properties contain the same information, but in different
2636         * forms (such as different languages). See {@link VCardParameters#getAltId
2637         * this description of the ALTID parameter} for more information. Note that
2638         * this method automatically assigns an appropriate ALTID parameter to each
2639         * property.
2640         * @see <a href="http://tools.ietf.org/html/rfc6350#page-22">RFC 6350
2641         * p.22</a>
2642         * @see <a href="http://tools.ietf.org/html/rfc2426#page-16">RFC 2426
2643         * p.16</a>
2644         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.16</a>
2645         */
2646        public void addTimezoneAlt(Timezone... altRepresentations) {
2647                addPropertyAlt(Timezone.class, altRepresentations);
2648        }
2649
2650        /**
2651         * <p>
2652         * Sets the timezone the person lives/works in.
2653         * </p>
2654         * <p>
2655         * <b>Property name:</b> {@code TZ}<br>
2656         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
2657         * </p>
2658         * @param timezone the timezone property or null to remove
2659         * @see <a href="http://tools.ietf.org/html/rfc6350#page-22">RFC 6350
2660         * p.22</a>
2661         * @see <a href="http://tools.ietf.org/html/rfc2426#page-16">RFC 2426
2662         * p.16</a>
2663         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.16</a>
2664         */
2665        public void setTimezone(Timezone timezone) {
2666                setProperty(Timezone.class, timezone);
2667        }
2668
2669        /**
2670         * <p>
2671         * Adds a timezone the person lives/works in.
2672         * </p>
2673         * <p>
2674         * <b>Property name:</b> {@code TZ}<br>
2675         * <b>Supported versions:</b> {@code 4.0*}<br>
2676         * <i>* Only 4.0 supports multiple instances</i>
2677         * </p>
2678         * @param timezone the timezone property to add
2679         * @see <a href="http://tools.ietf.org/html/rfc6350#page-22">RFC 6350
2680         * p.22</a>
2681         * @see <a href="http://tools.ietf.org/html/rfc2426#page-16">RFC 2426
2682         * p.16</a>
2683         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.16</a>
2684         */
2685        public void addTimezone(Timezone timezone) {
2686                addProperty(timezone);
2687        }
2688
2689        /**
2690         * <p>
2691         * Gets all instances of the {@link Geo} property.
2692         * </p>
2693         * <p>
2694         * Version 4.0 vCards may have multiple instances if alternative
2695         * representations are defined (see {@link #setGeoAlt(Geo...) setGeoAlt}) or
2696         * if properties with different TYPE parameters are defined.
2697         * </p>
2698         * <p>
2699         * <b>Property name:</b> {@code GEO}<br>
2700         * <b>Supported versions:</b> {@code 4.0*}<br>
2701         * <i>* Only 4.0 supports multiple instances</i>
2702         * </p>
2703         * @return the geo properties (any changes made this list will affect the
2704         * {@link VCard} object and vice versa)
2705         * @see <a href="http://tools.ietf.org/html/rfc6350#page-38">RFC 6350
2706         * p.38</a>
2707         * @see <a href="http://tools.ietf.org/html/rfc2426#page-16">RFC 2426
2708         * p.16</a>
2709         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.16</a>
2710         */
2711        public List<Geo> getGeos() {
2712                return getProperties(Geo.class);
2713        }
2714
2715        /**
2716         * <p>
2717         * Gets the geographical position of where the person lives/works.
2718         * </p>
2719         * <p>
2720         * <b>Property name:</b> {@code GEO}<br>
2721         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
2722         * </p>
2723         * @return the first geo property or null if not set
2724         * @see <a href="http://tools.ietf.org/html/rfc6350#page-38">RFC 6350
2725         * p.38</a>
2726         * @see <a href="http://tools.ietf.org/html/rfc2426#page-16">RFC 2426
2727         * p.16</a>
2728         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.16</a>
2729         */
2730        public Geo getGeo() {
2731                return getProperty(Geo.class);
2732        }
2733
2734        /**
2735         * <p>
2736         * Sets the geographical position of where the person lives/works.
2737         * </p>
2738         * <p>
2739         * <b>Property name:</b> {@code GEO}<br>
2740         * <b>Supported versions:</b> {@code 4.0*}<br>
2741         * <i>* Only 4.0 supports alternative representations</i>
2742         * </p>
2743         * @param altRepresentations the alternative representations of the same
2744         * value. These properties contain the same information, but in different
2745         * forms (such as different languages). See {@link VCardParameters#getAltId
2746         * this description of the ALTID parameter} for more information. Note that
2747         * this method automatically assigns an appropriate ALTID parameter to each
2748         * property.
2749         * @see <a href="http://tools.ietf.org/html/rfc6350#page-38">RFC 6350
2750         * p.38</a>
2751         * @see <a href="http://tools.ietf.org/html/rfc2426#page-16">RFC 2426
2752         * p.16</a>
2753         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.16</a>
2754         */
2755        public void setGeoAlt(Geo... altRepresentations) {
2756                setPropertyAlt(Geo.class, altRepresentations);
2757        }
2758
2759        /**
2760         * <p>
2761         * Adds a geographical position of where the person lives/works.
2762         * </p>
2763         * <p>
2764         * <b>Property name:</b> {@code GEO}<br>
2765         * <b>Supported versions:</b> {@code 4.0*}<br>
2766         * <i>* Only 4.0 supports alternative representations</i>
2767         * </p>
2768         * @param altRepresentations the alternative representations of the same
2769         * value. These properties contain the same information, but in different
2770         * forms (such as different languages). See {@link VCardParameters#getAltId
2771         * this description of the ALTID parameter} for more information. Note that
2772         * this method automatically assigns an appropriate ALTID parameter to each
2773         * property.
2774         * @see <a href="http://tools.ietf.org/html/rfc6350#page-38">RFC 6350
2775         * p.38</a>
2776         * @see <a href="http://tools.ietf.org/html/rfc2426#page-16">RFC 2426
2777         * p.16</a>
2778         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.16</a>
2779         */
2780        public void addGeoAlt(Geo... altRepresentations) {
2781                addPropertyAlt(Geo.class, altRepresentations);
2782        }
2783
2784        /**
2785         * <p>
2786         * Sets the geographical position of where the person lives/works.
2787         * </p>
2788         * <p>
2789         * <b>Property name:</b> {@code GEO}<br>
2790         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
2791         * </p>
2792         * @param geo the geo property or null to remove
2793         * @see <a href="http://tools.ietf.org/html/rfc6350#page-38">RFC 6350
2794         * p.38</a>
2795         * @see <a href="http://tools.ietf.org/html/rfc2426#page-16">RFC 2426
2796         * p.16</a>
2797         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.16</a>
2798         */
2799        public void setGeo(Geo geo) {
2800                setProperty(Geo.class, geo);
2801        }
2802
2803        /**
2804         * <p>
2805         * Adds a geographical position of where the person lives/works. Note that
2806         * only version 4.0 vCards support multiple instances of this property.
2807         * </p>
2808         * <p>
2809         * <b>Property name:</b> {@code GEO}<br>
2810         * <b>Supported versions:</b> {@code 4.0*}<br>
2811         * <i>* Only 4.0 supports multiple instances</i>
2812         * </p>
2813         * @param geo the geo property to add
2814         * @see <a href="http://tools.ietf.org/html/rfc6350#page-38">RFC 6350
2815         * p.38</a>
2816         * @see <a href="http://tools.ietf.org/html/rfc2426#page-16">RFC 2426
2817         * p.16</a>
2818         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.16</a>
2819         */
2820        public void addGeo(Geo geo) {
2821                addProperty(geo);
2822        }
2823
2824        /**
2825         * <p>
2826         * Sets the geographical position of where the person lives/works.
2827         * </p>
2828         * <p>
2829         * <b>Property name:</b> {@code GEO}<br>
2830         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
2831         * </p>
2832         * @param latitude the latitude
2833         * @param longitude the longitude
2834         * @return the property object that was created
2835         * @see <a href="http://tools.ietf.org/html/rfc6350#page-38">RFC 6350
2836         * p.38</a>
2837         * @see <a href="http://tools.ietf.org/html/rfc2426#page-16">RFC 2426
2838         * p.16</a>
2839         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.16</a>
2840         */
2841        public Geo setGeo(double latitude, double longitude) {
2842                Geo type = new Geo(latitude, longitude);
2843                setGeo(type);
2844                return type;
2845        }
2846
2847        /**
2848         * <p>
2849         * Gets all instances of the {@link Organization} property.
2850         * </p>
2851         * <p>
2852         * Version 4.0 vCards may have multiple instances if alternative
2853         * representations are defined (see
2854         * {@link #setOrganizationAlt(Organization...) setOrganizationAlt}) or if
2855         * properties with different TYPE parameters are defined.
2856         * </p>
2857         * <p>
2858         * <b>Property name:</b> {@code ORG}<br>
2859         * <b>Supported versions:</b> {@code 4.0*}<br>
2860         * <i>* Only 4.0 supports multiple instances</i>
2861         * </p>
2862         * @return the organization properties (any changes made this list will
2863         * affect the {@link VCard} object and vice versa)
2864         * @see <a href="http://tools.ietf.org/html/rfc6350#page-40">RFC 6350
2865         * p.40</a>
2866         * @see <a href="http://tools.ietf.org/html/rfc2426#page-20">RFC 2426
2867         * p.20</a>
2868         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.19</a>
2869         */
2870        public List<Organization> getOrganizations() {
2871                return getProperties(Organization.class);
2872        }
2873
2874        /**
2875         * <p>
2876         * Gets the hierarchy of department(s) to which the person belongs.
2877         * </p>
2878         * <p>
2879         * <b>Property name:</b> {@code ORG}<br>
2880         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
2881         * </p>
2882         * @return the first organization property or null if not set
2883         * @see <a href="http://tools.ietf.org/html/rfc6350#page-40">RFC 6350
2884         * p.40</a>
2885         * @see <a href="http://tools.ietf.org/html/rfc2426#page-20">RFC 2426
2886         * p.20</a>
2887         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.19</a>
2888         */
2889        public Organization getOrganization() {
2890                return getProperty(Organization.class);
2891        }
2892
2893        /**
2894         * <p>
2895         * Sets the hierarchy of department(s) to which the person belongs.
2896         * </p>
2897         * <p>
2898         * <b>Property name:</b> {@code ORG}<br>
2899         * <b>Supported versions:</b> {@code 4.0*}<br>
2900         * <i>* Only 4.0 supports alternative representations</i>
2901         * </p>
2902         * @param altRepresentations the alternative representations of the same
2903         * value. These properties contain the same information, but in different
2904         * forms (such as different languages). See {@link VCardParameters#getAltId
2905         * this description of the ALTID parameter} for more information. Note that
2906         * this method automatically assigns an appropriate ALTID parameter to each
2907         * property.
2908         * @see <a href="http://tools.ietf.org/html/rfc6350#page-40">RFC 6350
2909         * p.40</a>
2910         * @see <a href="http://tools.ietf.org/html/rfc2426#page-20">RFC 2426
2911         * p.20</a>
2912         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.19</a>
2913         */
2914        public void setOrganizationAlt(Organization... altRepresentations) {
2915                setPropertyAlt(Organization.class, altRepresentations);
2916        }
2917
2918        /**
2919         * <p>
2920         * Adds a hierarchy of department(s) to which the person belongs.
2921         * </p>
2922         * <p>
2923         * <b>Property name:</b> {@code ORG}<br>
2924         * <b>Supported versions:</b> {@code 4.0*}<br>
2925         * <i>* Only 4.0 supports alternative representations</i>
2926         * </p>
2927         * @param altRepresentations the alternative representations of the same
2928         * value. These properties contain the same information, but in different
2929         * forms (such as different languages). See {@link VCardParameters#getAltId
2930         * this description of the ALTID parameter} for more information. Note that
2931         * this method automatically assigns an appropriate ALTID parameter to each
2932         * property.
2933         * @see <a href="http://tools.ietf.org/html/rfc6350#page-40">RFC 6350
2934         * p.40</a>
2935         * @see <a href="http://tools.ietf.org/html/rfc2426#page-20">RFC 2426
2936         * p.20</a>
2937         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.19</a>
2938         */
2939        public void addOrganizationAlt(Organization... altRepresentations) {
2940                addPropertyAlt(Organization.class, altRepresentations);
2941        }
2942
2943        /**
2944         * <p>
2945         * Sets the hierarchy of departments to which the person belongs.
2946         * </p>
2947         * <p>
2948         * <b>Property name:</b> {@code ORG}<br>
2949         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
2950         * </p>
2951         * @param organization the organization property or null to remove
2952         * @see <a href="http://tools.ietf.org/html/rfc6350#page-40">RFC 6350
2953         * p.40</a>
2954         * @see <a href="http://tools.ietf.org/html/rfc2426#page-20">RFC 2426
2955         * p.20</a>
2956         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.19</a>
2957         */
2958        public void setOrganization(Organization organization) {
2959                setProperty(Organization.class, organization);
2960        }
2961
2962        /**
2963         * <p>
2964         * Adds a hierarchy of departments to which the person belongs. Note that
2965         * only version 4.0 vCards support multiple instances of this property.
2966         * </p>
2967         * <p>
2968         * <b>Property name:</b> {@code ORG}<br>
2969         * <b>Supported versions:</b> {@code 4.0*}<br>
2970         * <i>* Only 4.0 supports multiple instances</i>
2971         * </p>
2972         * @param organization the organization property to add
2973         * @see <a href="http://tools.ietf.org/html/rfc6350#page-40">RFC 6350
2974         * p.40</a>
2975         * @see <a href="http://tools.ietf.org/html/rfc2426#page-20">RFC 2426
2976         * p.20</a>
2977         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.19</a>
2978         */
2979        public void addOrganization(Organization organization) {
2980                addProperty(organization);
2981        }
2982
2983        /**
2984         * <p>
2985         * Sets the hierarchy of departments to which the person belongs.
2986         * </p>
2987         * <p>
2988         * <b>Property name:</b> {@code ORG}<br>
2989         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
2990         * </p>
2991         * @param departments the ordered list of department(s), starting with the
2992         * broadest and ending with the most specific (e.g. "Google", "Gmail Team",
2993         * "Spam Detection Squad") or an empty arguments list to remove
2994         * @return the property object that was created
2995         * @see <a href="http://tools.ietf.org/html/rfc6350#page-40">RFC 6350
2996         * p.40</a>
2997         * @see <a href="http://tools.ietf.org/html/rfc2426#page-20">RFC 2426
2998         * p.20</a>
2999         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.19</a>
3000         */
3001        public Organization setOrganization(String... departments) {
3002                Organization type = null;
3003                if (departments.length > 0) {
3004                        type = new Organization();
3005                        type.getValues().addAll(Arrays.asList(departments));
3006                }
3007                setOrganization(type);
3008                return type;
3009        }
3010
3011        /**
3012         * <p>
3013         * Gets all instances of the {@link Categories} property.
3014         * </p>
3015         * <p>
3016         * Version 4.0 vCards may have multiple instances if alternative
3017         * representations are defined (see {@link #setCategoriesAlt(Categories...)
3018         * setCategoriesAlt}) or if properties with different TYPE parameters are
3019         * defined.
3020         * </p>
3021         * <p>
3022         * <b>Property name:</b> {@code CATEGORIES}<br>
3023         * <b>Supported versions:</b> {@code 4.0*}<br>
3024         * <i>* Only 4.0 supports multiple instances</i>
3025         * </p>
3026         * @return the categories properties (any changes made this list will affect
3027         * the {@link VCard} object and vice versa)
3028         * @see <a href="http://tools.ietf.org/html/rfc6350#page-43">RFC 6350
3029         * p.43</a>
3030         * @see <a href="http://tools.ietf.org/html/rfc2426#page-20">RFC 2426
3031         * p.20</a>
3032         */
3033        public List<Categories> getCategoriesList() {
3034                return getProperties(Categories.class);
3035        }
3036
3037        /**
3038         * <p>
3039         * Gets the list of "keywords" or "tags" that can be used to describe the
3040         * person.
3041         * </p>
3042         * <p>
3043         * <b>Property name:</b> {@code CATEGORIES}<br>
3044         * <b>Supported versions:</b> {@code 3.0, 4.0}
3045         * </p>
3046         * @return the first categories property (can contain multiple values) or
3047         * null if not set
3048         * @see <a href="http://tools.ietf.org/html/rfc6350#page-43">RFC 6350
3049         * p.43</a>
3050         * @see <a href="http://tools.ietf.org/html/rfc2426#page-20">RFC 2426
3051         * p.20</a>
3052         */
3053        public Categories getCategories() {
3054                return getProperty(Categories.class);
3055        }
3056
3057        /**
3058         * <p>
3059         * Sets the list of "keywords" or "tags" that can be used to describe the
3060         * person.
3061         * </p>
3062         * <p>
3063         * <b>Property name:</b> {@code CATEGORIES}<br>
3064         * <b>Supported versions:</b> {@code 4.0*}<br>
3065         * <i>* Only 4.0 supports alternative representations</i>
3066         * </p>
3067         * @param altRepresentations the alternative representations of the same
3068         * value. These properties contain the same information, but in different
3069         * forms (such as different languages). See {@link VCardParameters#getAltId
3070         * this description of the ALTID parameter} for more information. Note that
3071         * this method automatically assigns an appropriate ALTID parameter to each
3072         * property.
3073         * @see <a href="http://tools.ietf.org/html/rfc6350#page-43">RFC 6350
3074         * p.43</a>
3075         * @see <a href="http://tools.ietf.org/html/rfc2426#page-20">RFC 2426
3076         * p.20</a>
3077         */
3078        public void setCategoriesAlt(Categories... altRepresentations) {
3079                setPropertyAlt(Categories.class, altRepresentations);
3080        }
3081
3082        /**
3083         * <p>
3084         * Adds a list of "keywords" or "tags" that can be used to describe the
3085         * person.
3086         * </p>
3087         * <p>
3088         * <b>Property name:</b> {@code CATEGORIES}<br>
3089         * <b>Supported versions:</b> {@code 4.0*}<br>
3090         * <i>* Only 4.0 supports alternative representations</i>
3091         * </p>
3092         * @param altRepresentations the alternative representations of the same
3093         * value. These properties contain the same information, but in different
3094         * forms (such as different languages). See {@link VCardParameters#getAltId
3095         * this description of the ALTID parameter} for more information. Note that
3096         * this method automatically assigns an appropriate ALTID parameter to each
3097         * property.
3098         * @see <a href="http://tools.ietf.org/html/rfc6350#page-43">RFC 6350
3099         * p.43</a>
3100         * @see <a href="http://tools.ietf.org/html/rfc2426#page-20">RFC 2426
3101         * p.20</a>
3102         */
3103        public void addCategoriesAlt(Categories... altRepresentations) {
3104                addPropertyAlt(Categories.class, altRepresentations);
3105        }
3106
3107        /**
3108         * <p>
3109         * Sets the list of "keywords" or "tags" that can be used to describe the
3110         * person.
3111         * </p>
3112         * <p>
3113         * <b>Property name:</b> {@code CATEGORIES}<br>
3114         * <b>Supported versions:</b> {@code 3.0, 4.0}
3115         * </p>
3116         * @param categories the categories property (can contain multiple values)
3117         * or null to remove
3118         * @see <a href="http://tools.ietf.org/html/rfc6350#page-43">RFC 6350
3119         * p.43</a>
3120         * @see <a href="http://tools.ietf.org/html/rfc2426#page-20">RFC 2426
3121         * p.20</a>
3122         */
3123        public void setCategories(Categories categories) {
3124                setProperty(Categories.class, categories);
3125        }
3126
3127        /**
3128         * <p>
3129         * Adds a list of "keywords" or "tags" that can be used to describe the
3130         * person. Note that only version 4.0 vCards support multiple instances of
3131         * this property.
3132         * </p>
3133         * <p>
3134         * <b>Property name:</b> {@code CATEGORIES}<br>
3135         * <b>Supported versions:</b> {@code 4.0*}<br>
3136         * <i>* Only 4.0 supports multiple instances</i>
3137         * </p>
3138         * @param categories the categories property to add (can contain multiple
3139         * values)
3140         * @see <a href="http://tools.ietf.org/html/rfc6350#page-43">RFC 6350
3141         * p.43</a>
3142         * @see <a href="http://tools.ietf.org/html/rfc2426#page-20">RFC 2426
3143         * p.20</a>
3144         */
3145        public void addCategories(Categories categories) {
3146                addProperty(categories);
3147        }
3148
3149        /**
3150         * <p>
3151         * Sets the list of "keywords" or "tags" that can be used to describe the
3152         * person.
3153         * </p>
3154         * <p>
3155         * <b>Property name:</b> {@code CATEGORIES}<br>
3156         * <b>Supported versions:</b> {@code 3.0, 4.0}
3157         * </p>
3158         * @param categories the categories (e.g. "swimmer", "biker", "knitter") or
3159         * an empty arguments list to remove
3160         * @return the property object that was created
3161         * @see <a href="http://tools.ietf.org/html/rfc6350#page-43">RFC 6350
3162         * p.43</a>
3163         * @see <a href="http://tools.ietf.org/html/rfc2426#page-20">RFC 2426
3164         * p.20</a>
3165         */
3166        public Categories setCategories(String... categories) {
3167                Categories type = null;
3168                if (categories.length > 0) {
3169                        type = new Categories();
3170                        type.getValues().addAll(Arrays.asList(categories));
3171                }
3172                setCategories(type);
3173                return type;
3174        }
3175
3176        /**
3177         * <p>
3178         * Gets information about the person's agent.
3179         * </p>
3180         * <p>
3181         * <b>Property name:</b> {@code AGENT}<br>
3182         * <b>Supported versions:</b> {@code 2.1, 3.0}
3183         * </p>
3184         * @return the agent property or null if not set
3185         * @see <a href="http://tools.ietf.org/html/rfc2426#page-19">RFC 2426
3186         * p.19</a>
3187         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.18</a>
3188         */
3189        public Agent getAgent() {
3190                return getProperty(Agent.class);
3191        }
3192
3193        /**
3194         * <p>
3195         * Sets information about the person's agent.
3196         * </p>
3197         * <p>
3198         * <b>Property name:</b> {@code AGENT}<br>
3199         * <b>Supported versions:</b> {@code 2.1, 3.0}
3200         * </p>
3201         * @param agent the agent property or null to remove
3202         * @see <a href="http://tools.ietf.org/html/rfc2426#page-19">RFC 2426
3203         * p.19</a>
3204         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.18</a>
3205         */
3206        public void setAgent(Agent agent) {
3207                setProperty(Agent.class, agent);
3208        }
3209
3210        /**
3211         * <p>
3212         * Gets the notes. Notes contain free-form, miscellaneous text.
3213         * </p>
3214         * <p>
3215         * <b>Property name:</b> {@code NOTE}<br>
3216         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
3217         * </p>
3218         * @return the note properties (any changes made this list will affect the
3219         * {@link VCard} object and vice versa)
3220         * @see <a href="http://tools.ietf.org/html/rfc6350#page-44">RFC 6350
3221         * p.44</a>
3222         * @see <a href="http://tools.ietf.org/html/rfc2426#page-21">RFC 2426
3223         * p.21</a>
3224         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.19</a>
3225         */
3226        public List<Note> getNotes() {
3227                return getProperties(Note.class);
3228        }
3229
3230        /**
3231         * <p>
3232         * Adds a note. Notes contain free-form, miscellaneous text.
3233         * </p>
3234         * <p>
3235         * <b>Property name:</b> {@code NOTE}<br>
3236         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
3237         * </p>
3238         * @param note the note property to add
3239         * @see <a href="http://tools.ietf.org/html/rfc6350#page-44">RFC 6350
3240         * p.44</a>
3241         * @see <a href="http://tools.ietf.org/html/rfc2426#page-21">RFC 2426
3242         * p.21</a>
3243         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.19</a>
3244         */
3245        public void addNote(Note note) {
3246                addProperty(note);
3247        }
3248
3249        /**
3250         * <p>
3251         * Adds a note. Notes contain free-form, miscellaneous text.
3252         * </p>
3253         * <p>
3254         * <b>Property name:</b> {@code NOTE}<br>
3255         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
3256         * </p>
3257         * @param note the note to add
3258         * @return the property object that was created
3259         * @see <a href="http://tools.ietf.org/html/rfc6350#page-44">RFC 6350
3260         * p.44</a>
3261         * @see <a href="http://tools.ietf.org/html/rfc2426#page-21">RFC 2426
3262         * p.21</a>
3263         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.19</a>
3264         */
3265        public Note addNote(String note) {
3266                Note type = new Note(note);
3267                addNote(type);
3268                return type;
3269        }
3270
3271        /**
3272         * <p>
3273         * Adds a note. Notes contain free-form, miscellaneous text.
3274         * </p>
3275         * <p>
3276         * <b>Property name:</b> {@code NOTE}<br>
3277         * <b>Supported versions:</b> {@code 4.0*}<br>
3278         * <i>* Only 4.0 supports alternative representations</i>
3279         * </p>
3280         * @param altRepresentations the alternative representations of the same
3281         * value. These properties contain the same information, but in different
3282         * forms (such as different languages). See {@link VCardParameters#getAltId
3283         * this description of the ALTID parameter} for more information. Note that
3284         * this method automatically assigns an appropriate ALTID parameter to each
3285         * property.
3286         * @see <a href="http://tools.ietf.org/html/rfc6350#page-44">RFC 6350
3287         * p.44</a>
3288         * @see <a href="http://tools.ietf.org/html/rfc2426#page-21">RFC 2426
3289         * p.21</a>
3290         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.19</a>
3291         */
3292        public void addNoteAlt(Note... altRepresentations) {
3293                addPropertyAlt(Note.class, altRepresentations);
3294        }
3295
3296        /**
3297         * <p>
3298         * Gets the unique identifier of the vCard.
3299         * </p>
3300         * <p>
3301         * <b>Property name:</b> {@code UID}<br>
3302         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
3303         * </p>
3304         * @return the unique identifier property or null if not set
3305         * @see <a href="http://tools.ietf.org/html/rfc6350#page-46">RFC 6350
3306         * p.46</a>
3307         * @see <a href="http://tools.ietf.org/html/rfc2426#page-24">RFC 2426
3308         * p.24</a>
3309         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.21</a>
3310         */
3311        public Uid getUid() {
3312                return getProperty(Uid.class);
3313        }
3314
3315        /**
3316         * <p>
3317         * Sets the unique identifier of the vCard.
3318         * </p>
3319         * <p>
3320         * <b>Property name:</b> {@code UID}<br>
3321         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
3322         * </p>
3323         * @param uid the unique identifier property or null to remove
3324         * @see <a href="http://tools.ietf.org/html/rfc6350#page-46">RFC 6350
3325         * p.46</a>
3326         * @see <a href="http://tools.ietf.org/html/rfc2426#page-24">RFC 2426
3327         * p.24</a>
3328         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.21</a>
3329         */
3330        public void setUid(Uid uid) {
3331                setProperty(Uid.class, uid);
3332        }
3333
3334        /**
3335         * <p>
3336         * Gets the public encryption keys.
3337         * </p>
3338         * <p>
3339         * <b>Property name:</b> {@code KEY}<br>
3340         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
3341         * </p>
3342         * @return the key properties (any changes made this list will affect the
3343         * {@link VCard} object and vice versa)
3344         * @see <a href="http://tools.ietf.org/html/rfc6350#page-48">RFC 6350
3345         * p.48</a>
3346         * @see <a href="http://tools.ietf.org/html/rfc2426#page-26">RFC 2426
3347         * p.26</a>
3348         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.22</a>
3349         */
3350        public List<Key> getKeys() {
3351                return getProperties(Key.class);
3352        }
3353
3354        /**
3355         * <p>
3356         * Adds a public encryption key.
3357         * </p>
3358         * <p>
3359         * <b>Property name:</b> {@code KEY}<br>
3360         * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
3361         * </p>
3362         * @param key the key property to add
3363         * @see <a href="http://tools.ietf.org/html/rfc6350#page-48">RFC 6350
3364         * p.48</a>
3365         * @see <a href="http://tools.ietf.org/html/rfc2426#page-26">RFC 2426
3366         * p.26</a>
3367         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.22</a>
3368         */
3369        public void addKey(Key key) {
3370                addProperty(key);
3371        }
3372
3373        /**
3374         * <p>
3375         * Adds a public encryption key.
3376         * </p>
3377         * <p>
3378         * <b>Property name:</b> {@code KEY}<br>
3379         * <b>Supported versions:</b> {@code 4.0*}<br>
3380         * <i>* Only 4.0 supports alternative representations</i>
3381         * </p>
3382         * @param altRepresentations the alternative representations of the same
3383         * value. These properties contain the same information, but in different
3384         * forms (such as different languages). See {@link VCardParameters#getAltId
3385         * this description of the ALTID parameter} for more information. Note that
3386         * this method automatically assigns an appropriate ALTID parameter to each
3387         * property.
3388         * @see <a href="http://tools.ietf.org/html/rfc6350#page-48">RFC 6350
3389         * p.48</a>
3390         * @see <a href="http://tools.ietf.org/html/rfc2426#page-26">RFC 2426
3391         * p.26</a>
3392         * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.22</a>
3393         */
3394        public void addKeyAlt(Key... altRepresentations) {
3395                addPropertyAlt(Key.class, altRepresentations);
3396        }
3397
3398        /**
3399         * <p>
3400         * Gets the instant messaging handles.
3401         * </p>
3402         * <p>
3403         * <b>Property name:</b> {@code IMPP}<br>
3404         * <b>Supported versions:</b> {@code 3.0, 4.0}
3405         * </p>
3406         * @return the IMPP properties (any changes made this list will affect the
3407         * {@link VCard} object and vice versa)
3408         * @see <a href="http://tools.ietf.org/html/rfc6350#page-36">RFC 6350
3409         * p.36</a>
3410         * @see <a href="http://tools.ietf.org/html/rfc4770">RFC 4770</a>
3411         */
3412        public List<Impp> getImpps() {
3413                return getProperties(Impp.class);
3414        }
3415
3416        /**
3417         * <p>
3418         * Adds an instant messaging handle.
3419         * </p>
3420         * <p>
3421         * <b>Property name:</b> {@code IMPP}<br>
3422         * <b>Supported versions:</b> {@code 3.0, 4.0}
3423         * </p>
3424         * @param impp the IMPP property to add
3425         * @see <a href="http://tools.ietf.org/html/rfc6350#page-36">RFC 6350
3426         * p.36</a>
3427         * @see <a href="http://tools.ietf.org/html/rfc4770">RFC 4770</a>
3428         */
3429        public void addImpp(Impp impp) {
3430                addProperty(impp);
3431        }
3432
3433        /**
3434         * <p>
3435         * Adds an instant messaging handle.
3436         * </p>
3437         * <p>
3438         * <b>Property name:</b> {@code IMPP}<br>
3439         * <b>Supported versions:</b> {@code 4.0*}<br>
3440         * <i>* Only 4.0 supports alternative representations</i>
3441         * </p>
3442         * @param altRepresentations the alternative representations of the same
3443         * value. These properties contain the same information, but in different
3444         * forms (such as different languages). See {@link VCardParameters#getAltId
3445         * this description of the ALTID parameter} for more information. Note that
3446         * this method automatically assigns an appropriate ALTID parameter to each
3447         * property.
3448         * @see <a href="http://tools.ietf.org/html/rfc6350#page-36">RFC 6350
3449         * p.36</a>
3450         * @see <a href="http://tools.ietf.org/html/rfc4770">RFC 4770</a>
3451         */
3452        public void addImppAlt(Impp... altRepresentations) {
3453                addPropertyAlt(Impp.class, altRepresentations);
3454        }
3455
3456        /**
3457         * <p>
3458         * Gets a list of people that the person is related to.
3459         * </p>
3460         * <p>
3461         * <b>Property name:</b> {@code RELATED}<br>
3462         * <b>Supported versions:</b> {@code 4.0}
3463         * </p>
3464         * @return the relation properties (any changes made this list will affect
3465         * the {@link VCard} object and vice versa)
3466         * @see <a href="http://tools.ietf.org/html/rfc6350#page-42">RFC 6350
3467         * p.42</a>
3468         */
3469        public List<Related> getRelations() {
3470                return getProperties(Related.class);
3471        }
3472
3473        /**
3474         * <p>
3475         * Adds someone that the person is related to.
3476         * </p>
3477         * <p>
3478         * <b>Property name:</b> {@code RELATED}<br>
3479         * <b>Supported versions:</b> {@code 4.0}
3480         * </p>
3481         * @param related the relation property to add
3482         * @see <a href="http://tools.ietf.org/html/rfc6350#page-42">RFC 6350
3483         * p.42</a>
3484         */
3485        public void addRelated(Related related) {
3486                addProperty(related);
3487        }
3488
3489        /**
3490         * <p>
3491         * Adds someone that the person is related to.
3492         * </p>
3493         * <p>
3494         * <b>Property name:</b> {@code RELATED}<br>
3495         * <b>Supported versions:</b> {@code 4.0}
3496         * </p>
3497         * @param altRepresentations the alternative representations of the same
3498         * value. These properties contain the same information, but in different
3499         * forms (such as different languages). See {@link VCardParameters#getAltId
3500         * this description of the ALTID parameter} for more information. Note that
3501         * this method automatically assigns an appropriate ALTID parameter to each
3502         * property.
3503         * @see <a href="http://tools.ietf.org/html/rfc6350#page-42">RFC 6350
3504         * p.42</a>
3505         */
3506        public void addRelatedAlt(Related... altRepresentations) {
3507                addPropertyAlt(Related.class, altRepresentations);
3508        }
3509
3510        /**
3511         * <p>
3512         * Gets the languages that the person speaks.
3513         * </p>
3514         * <p>
3515         * <b>Property name:</b> {@code LANG}<br>
3516         * <b>Supported versions:</b> {@code 4.0}
3517         * </p>
3518         * @return the language properties (any changes made this list will affect
3519         * the {@link VCard} object and vice versa)
3520         * @see <a href="http://tools.ietf.org/html/rfc6350#page-37">RFC 6350
3521         * p.37</a>
3522         */
3523        public List<Language> getLanguages() {
3524                return getProperties(Language.class);
3525        }
3526
3527        /**
3528         * <p>
3529         * Adds a language that the person speaks.
3530         * </p>
3531         * <p>
3532         * <b>Property name:</b> {@code LANG}<br>
3533         * <b>Supported versions:</b> {@code 4.0}
3534         * </p>
3535         * @param language the language property to add
3536         * @see <a href="http://tools.ietf.org/html/rfc6350#page-37">RFC 6350
3537         * p.37</a>
3538         */
3539        public void addLanguage(Language language) {
3540                addProperty(language);
3541        }
3542
3543        /**
3544         * <p>
3545         * Adds a language that the person speaks.
3546         * </p>
3547         * <p>
3548         * <b>Property name:</b> {@code LANG}<br>
3549         * <b>Supported versions:</b> {@code 4.0}
3550         * </p>
3551         * @param language the language to add (e.g. "en-us")
3552         * @return the property object that was created
3553         * @see <a href="http://tools.ietf.org/html/rfc6350#page-37">RFC 6350
3554         * p.37</a>
3555         */
3556        public Language addLanguage(String language) {
3557                Language type = new Language(language);
3558                addLanguage(type);
3559                return type;
3560        }
3561
3562        /**
3563         * <p>
3564         * Adds a language that the person speaks.
3565         * </p>
3566         * <p>
3567         * <b>Property name:</b> {@code LANG}<br>
3568         * <b>Supported versions:</b> {@code 4.0}
3569         * @param altRepresentations the alternative representations of the same
3570         * value. These properties contain the same information, but in different
3571         * forms (such as different languages). See {@link VCardParameters#getAltId
3572         * this description of the ALTID parameter} for more information. Note that
3573         * this method automatically assigns an appropriate ALTID parameter to each
3574         * property.
3575         * @see <a href="http://tools.ietf.org/html/rfc6350#page-37">RFC 6350
3576         * p.37</a>
3577         */
3578        public void addLanguageAlt(Language... altRepresentations) {
3579                addPropertyAlt(Language.class, altRepresentations);
3580        }
3581
3582        /**
3583         * <p>
3584         * Gets the URIs that can be used to schedule a meeting with the person on
3585         * his or her calendar.
3586         * </p>
3587         * <p>
3588         * <b>Property name:</b> {@code CALADRURI}<br>
3589         * <b>Supported versions:</b> {@code 4.0}
3590         * </p>
3591         * @return the calendar request URI properties (any changes made this list
3592         * will affect the {@link VCard} object and vice versa)
3593         * @see <a href="http://tools.ietf.org/html/rfc6350#page-50">RFC 6350
3594         * p.50</a>
3595         */
3596        public List<CalendarRequestUri> getCalendarRequestUris() {
3597                return getProperties(CalendarRequestUri.class);
3598        }
3599
3600        /**
3601         * <p>
3602         * Adds a URI that can be used to schedule a meeting with the person on his
3603         * or her calendar.
3604         * </p>
3605         * <p>
3606         * <b>Property name:</b> {@code CALADRURI}<br>
3607         * <b>Supported versions:</b> {@code 4.0}
3608         * </p>
3609         * @param calendarRequestUri the calendar request URI property to add
3610         * @see <a href="http://tools.ietf.org/html/rfc6350#page-50">RFC 6350
3611         * p.50</a>
3612         */
3613        public void addCalendarRequestUri(CalendarRequestUri calendarRequestUri) {
3614                addProperty(calendarRequestUri);
3615        }
3616
3617        /**
3618         * <p>
3619         * Adds a URI that can be used to schedule a meeting with the person on his
3620         * or her calendar.
3621         * </p>
3622         * <p>
3623         * <b>Property name:</b> {@code CALADRURI}<br>
3624         * <b>Supported versions:</b> {@code 4.0}
3625         * </p>
3626         * @param altRepresentations the alternative representations of the same
3627         * value. These properties contain the same information, but in different
3628         * forms (such as different languages). See {@link VCardParameters#getAltId
3629         * this description of the ALTID parameter} for more information. Note that
3630         * this method automatically assigns an appropriate ALTID parameter to each
3631         * property.
3632         * @see <a href="http://tools.ietf.org/html/rfc6350#page-50">RFC 6350
3633         * p.50</a>
3634         */
3635        public void addCalendarRequestUriAlt(CalendarRequestUri... altRepresentations) {
3636                addPropertyAlt(CalendarRequestUri.class, altRepresentations);
3637        }
3638
3639        /**
3640         * <p>
3641         * Gets the URIs that point to the person's calendar.
3642         * </p>
3643         * <p>
3644         * <b>Property name:</b> {@code CALURI}<br>
3645         * <b>Supported versions:</b> {@code 4.0}
3646         * </p>
3647         * @return the calendar URI properties (any changes made this list will
3648         * affect the {@link VCard} object and vice versa)
3649         * @see <a href="http://tools.ietf.org/html/rfc6350#page-50">RFC 6350
3650         * p.50</a>
3651         */
3652        public List<CalendarUri> getCalendarUris() {
3653                return getProperties(CalendarUri.class);
3654        }
3655
3656        /**
3657         * <p>
3658         * Adds a URI that points to the person's calendar.
3659         * </p>
3660         * <p>
3661         * <b>Property name:</b> {@code CALURI}<br>
3662         * <b>Supported versions:</b> {@code 4.0}
3663         * </p>
3664         * @param calendarUri the calendar URI property to add
3665         * @see <a href="http://tools.ietf.org/html/rfc6350#page-50">RFC 6350
3666         * p.50</a>
3667         */
3668        public void addCalendarUri(CalendarUri calendarUri) {
3669                addProperty(calendarUri);
3670        }
3671
3672        /**
3673         * <p>
3674         * Adds a URI that points to the person's calendar.
3675         * </p>
3676         * <p>
3677         * <b>Property name:</b> {@code CALURI}<br>
3678         * <b>Supported versions:</b> {@code 4.0}
3679         * </p>
3680         * @param altRepresentations the alternative representations of the same
3681         * value. These properties contain the same information, but in different
3682         * forms (such as different languages). See {@link VCardParameters#getAltId
3683         * this description of the ALTID parameter} for more information. Note that
3684         * this method automatically assigns an appropriate ALTID parameter to each
3685         * property.
3686         * @see <a href="http://tools.ietf.org/html/rfc6350#page-50">RFC 6350
3687         * p.50</a>
3688         */
3689        public void addCalendarUriAlt(CalendarUri... altRepresentations) {
3690                addPropertyAlt(CalendarUri.class, altRepresentations);
3691        }
3692
3693        /**
3694         * <p>
3695         * Gets the URLs that can be used to determine when the person is free or
3696         * busy.
3697         * </p>
3698         * <p>
3699         * <b>Property name:</b> {@code FBURL}<br>
3700         * <b>Supported versions:</b> {@code 4.0}
3701         * </p>
3702         * @return the free-busy URL properties (any changes made this list will
3703         * affect the {@link VCard} object and vice versa)
3704         * @see <a href="http://tools.ietf.org/html/rfc6350#page-49">RFC 6350
3705         * p.49</a>
3706         */
3707        public List<FreeBusyUrl> getFbUrls() {
3708                return getProperties(FreeBusyUrl.class);
3709        }
3710
3711        /**
3712         * <p>
3713         * Adds a URL that can be used to determine when the person is free or busy.
3714         * </p>
3715         * <p>
3716         * <b>Property name:</b> {@code FBURL}<br>
3717         * <b>Supported versions:</b> {@code 4.0}
3718         * </p>
3719         * @param fbUrl the free-busy URL property to add
3720         * @see <a href="http://tools.ietf.org/html/rfc6350#page-49">RFC 6350
3721         * p.49</a>
3722         */
3723        public void addFbUrl(FreeBusyUrl fbUrl) {
3724                addProperty(fbUrl);
3725        }
3726
3727        /**
3728         * <p>
3729         * Adds a URL that can be used to determine when the person is free or busy.
3730         * </p>
3731         * <p>
3732         * <b>Property name:</b> {@code FBURL}<br>
3733         * <b>Supported versions:</b> {@code 4.0}
3734         * </p>
3735         * @param altRepresentations the alternative representations of the same
3736         * value. These properties contain the same information, but in different
3737         * forms (such as different languages). See {@link VCardParameters#getAltId
3738         * this description of the ALTID parameter} for more information. Note that
3739         * this method automatically assigns an appropriate ALTID parameter to each
3740         * property.
3741         * @see <a href="http://tools.ietf.org/html/rfc6350#page-49">RFC 6350
3742         * p.49</a>
3743         */
3744        public void addFbUrlAlt(FreeBusyUrl... altRepresentations) {
3745                addPropertyAlt(FreeBusyUrl.class, altRepresentations);
3746        }
3747
3748        /**
3749         * <p>
3750         * Gets the properties that are used to assign globally-unique identifiers
3751         * to individual property instances. They are used for merging together
3752         * different versions of the same vCard.
3753         * </p>
3754         * <p>
3755         * <b>Property name:</b> {@code CLIENTPIDMAP}<br>
3756         * <b>Supported versions:</b> {@code 4.0}
3757         * </p>
3758         * @return the client PID map properties (any changes made this list will
3759         * affect the {@link VCard} object and vice versa)
3760         * @see <a href="http://tools.ietf.org/html/rfc6350#page-47">RFC 6350
3761         * p.47</a>
3762         */
3763        public List<ClientPidMap> getClientPidMaps() {
3764                return getProperties(ClientPidMap.class);
3765        }
3766
3767        /**
3768         * <p>
3769         * Adds a property that is used to assign a globally-unique identifier to an
3770         * individual property instance. They are used for merging together
3771         * different versions of the same vCard.
3772         * </p>
3773         * <p>
3774         * <b>Property name:</b> {@code CLIENTPIDMAP}<br>
3775         * <b>Supported versions:</b> {@code 4.0}
3776         * </p>
3777         * @param clientPidMap the client PID map property to add
3778         * @see <a href="http://tools.ietf.org/html/rfc6350#page-47">RFC 6350
3779         * p.47</a>
3780         */
3781        public void addClientPidMap(ClientPidMap clientPidMap) {
3782                addProperty(clientPidMap);
3783        }
3784
3785        /**
3786         * <p>
3787         * Gets any XML data that is attached to the vCard.
3788         * </p>
3789         * <p>
3790         * These properties may be present if the vCard was encoded in XML ("xCard"
3791         * format) and the XML document contained non-standard elements. In this
3792         * case, the properties would contain all of the non-standard XML elements.
3793         * </p>
3794         * <p>
3795         * <b>Property name:</b> {@code XML}<br>
3796         * <b>Supported versions:</b> {@code 4.0}
3797         * </p>
3798         * @return the XML properties (any changes made this list will affect the
3799         * {@link VCard} object and vice versa)
3800         * @see <a href="http://tools.ietf.org/html/rfc6350#page-27">RFC 6350
3801         * p.27</a>
3802         */
3803        public List<Xml> getXmls() {
3804                return getProperties(Xml.class);
3805        }
3806
3807        /**
3808         * <p>
3809         * Adds XML data to the vCard.
3810         * </p>
3811         * <p>
3812         * These properties may be present if the vCard was encoded in XML ("xCard"
3813         * format) and the XML document contained non-standard elements. In this
3814         * case, the properties would contain all of the non-standard XML elements.
3815         * </p>
3816         * <p>
3817         * <b>Property name:</b> {@code XML}<br>
3818         * <b>Supported versions:</b> {@code 4.0}
3819         * </p>
3820         * @param xml the XML property to add
3821         * @see <a href="http://tools.ietf.org/html/rfc6350#page-27">RFC 6350
3822         * p.27</a>
3823         */
3824        public void addXml(Xml xml) {
3825                addProperty(xml);
3826        }
3827
3828        /**
3829         * <p>
3830         * Adds XML data to the vCard.
3831         * </p>
3832         * <p>
3833         * These properties may be present if the vCard was encoded in XML ("xCard"
3834         * format) and the XML document contained non-standard elements. In this
3835         * case, the properties would contain all of the non-standard XML elements.
3836         * </p>
3837         * <p>
3838         * <b>Property name:</b> {@code XML}<br>
3839         * <b>Supported versions:</b> {@code 4.0}
3840         * </p>
3841         * @param altRepresentations the alternative representations of the same
3842         * value. These properties contain the same information, but in different
3843         * forms (such as different languages). See {@link VCardParameters#getAltId
3844         * this description of the ALTID parameter} for more information. Note that
3845         * this method automatically assigns an appropriate ALTID parameter to each
3846         * property.
3847         * @see <a href="http://tools.ietf.org/html/rfc6350#page-27">RFC 6350
3848         * p.27</a>
3849         */
3850        public void addXmlAlt(Xml... altRepresentations) {
3851                addPropertyAlt(Xml.class, altRepresentations);
3852        }
3853
3854        /**
3855         * <p>
3856         * Gets the professional subject areas that the person is knowledgeable in.
3857         * </p>
3858         * <p>
3859         * <b>Property name:</b> {@code EXPERTISE}<br>
3860         * <b>Supported versions:</b> {@code 4.0}
3861         * </p>
3862         * @return the expertise properties (any changes made this list will affect
3863         * the {@link VCard} object and vice versa)
3864         * @see <a href="http://tools.ietf.org/html/rfc6715#page-3">RFC 6715 p.3</a>
3865         */
3866        public List<Expertise> getExpertise() {
3867                return getProperties(Expertise.class);
3868        }
3869
3870        /**
3871         * <p>
3872         * Adds a professional subject area that the person is knowledgeable in.
3873         * </p>
3874         * <p>
3875         * <b>Property name:</b> {@code EXPERTISE}<br>
3876         * <b>Supported versions:</b> {@code 4.0}
3877         * </p>
3878         * @param expertise the expertise property to add
3879         * @see <a href="http://tools.ietf.org/html/rfc6715#page-3">RFC 6715 p.3</a>
3880         */
3881        public void addExpertise(Expertise expertise) {
3882                addProperty(expertise);
3883        }
3884
3885        /**
3886         * <p>
3887         * Adds a professional subject area that the person is knowledgeable in.
3888         * </p>
3889         * <p>
3890         * <b>Property name:</b> {@code EXPERTISE}<br>
3891         * <b>Supported versions:</b> {@code 4.0}
3892         * </p>
3893         * @param expertise the professional subject area to add (e.g.
3894         * "programming")
3895         * @return the property object that was created
3896         * @see <a href="http://tools.ietf.org/html/rfc6715#page-3">RFC 6715 p.3</a>
3897         */
3898        public Expertise addExpertise(String expertise) {
3899                Expertise type = new Expertise(expertise);
3900                addExpertise(type);
3901                return type;
3902        }
3903
3904        /**
3905         * <p>
3906         * Adds a professional subject area that the person is knowledgeable in.
3907         * </p>
3908         * <p>
3909         * <b>Property name:</b> {@code EXPERTISE}<br>
3910         * <b>Supported versions:</b> {@code 4.0}
3911         * </p>
3912         * @param altRepresentations the alternative representations of the same
3913         * value. These properties contain the same information, but in different
3914         * forms (such as different languages). See {@link VCardParameters#getAltId
3915         * this description of the ALTID parameter} for more information. Note that
3916         * this method automatically assigns an appropriate ALTID parameter to each
3917         * property.
3918         * @see <a href="http://tools.ietf.org/html/rfc6715#page-3">RFC 6715 p.3</a>
3919         */
3920        public void addExpertiseAlt(Expertise... altRepresentations) {
3921                addPropertyAlt(Expertise.class, altRepresentations);
3922        }
3923
3924        /**
3925         * <p>
3926         * Gets the hobbies that the person actively engages in.
3927         * </p>
3928         * <p>
3929         * <b>Property name:</b> {@code HOBBY}<br>
3930         * <b>Supported versions:</b> {@code 4.0}
3931         * </p>
3932         * @return the hobby properties (any changes made this list will affect the
3933         * {@link VCard} object and vice versa)
3934         * @see <a href="http://tools.ietf.org/html/rfc6715#page-4">RFC 6715 p.4</a>
3935         */
3936        public List<Hobby> getHobbies() {
3937                return getProperties(Hobby.class);
3938        }
3939
3940        /**
3941         * <p>
3942         * Adds a hobby that the person actively engages in.
3943         * </p>
3944         * <p>
3945         * <b>Property name:</b> {@code HOBBY}<br>
3946         * <b>Supported versions:</b> {@code 4.0}
3947         * </p>
3948         * @param hobby the hobby property to add
3949         * @see <a href="http://tools.ietf.org/html/rfc6715#page-4">RFC 6715 p.4</a>
3950         */
3951        public void addHobby(Hobby hobby) {
3952                addProperty(hobby);
3953        }
3954
3955        /**
3956         * <p>
3957         * Adds a hobby that the person actively engages in.
3958         * </p>
3959         * <p>
3960         * <b>Property name:</b> {@code HOBBY}<br>
3961         * <b>Supported versions:</b> {@code 4.0}
3962         * </p>
3963         * @param hobby the hobby to add (e.g. "photography")
3964         * @return the property object that was created
3965         * @see <a href="http://tools.ietf.org/html/rfc6715#page-4">RFC 6715 p.4</a>
3966         */
3967        public Hobby addHobby(String hobby) {
3968                Hobby type = new Hobby(hobby);
3969                addHobby(type);
3970                return type;
3971        }
3972
3973        /**
3974         * <p>
3975         * Adds a hobby that the person actively engages in.
3976         * </p>
3977         * <p>
3978         * <b>Property name:</b> {@code HOBBY}<br>
3979         * <b>Supported versions:</b> {@code 4.0}
3980         * </p>
3981         * @param altRepresentations the alternative representations of the same
3982         * value. These properties contain the same information, but in different
3983         * forms (such as different languages). See {@link VCardParameters#getAltId
3984         * this description of the ALTID parameter} for more information. Note that
3985         * this method automatically assigns an appropriate ALTID parameter to each
3986         * property.
3987         * @see <a href="http://tools.ietf.org/html/rfc6715#page-4">RFC 6715 p.4</a>
3988         */
3989        public void addHobbyAlt(Hobby... altRepresentations) {
3990                addPropertyAlt(Hobby.class, altRepresentations);
3991        }
3992
3993        /**
3994         * <p>
3995         * Gets the person's interests.
3996         * </p>
3997         * <p>
3998         * <b>Property name:</b> {@code INTEREST}<br>
3999         * <b>Supported versions:</b> {@code 4.0}
4000         * </p>
4001         * @return the interest properties (any changes made this list will affect
4002         * the {@link VCard} object and vice versa)
4003         * @see <a href="http://tools.ietf.org/html/rfc6715#page-5">RFC 6715 p.5</a>
4004         */
4005        public List<Interest> getInterests() {
4006                return getProperties(Interest.class);
4007        }
4008
4009        /**
4010         * <p>
4011         * Adds an interest.
4012         * </p>
4013         * <p>
4014         * <b>Property name:</b> {@code INTEREST}<br>
4015         * <b>Supported versions:</b> {@code 4.0}
4016         * </p>
4017         * @param interest the interest property to add
4018         * @see <a href="http://tools.ietf.org/html/rfc6715#page-5">RFC 6715 p.5</a>
4019         */
4020        public void addInterest(Interest interest) {
4021                addProperty(interest);
4022        }
4023
4024        /**
4025         * <p>
4026         * Adds an interest.
4027         * </p>
4028         * <p>
4029         * <b>Property name:</b> {@code INTEREST}<br>
4030         * <b>Supported versions:</b> {@code 4.0}
4031         * </p>
4032         * @param interest the interest to add (e.g. "football")
4033         * @return the property object that was created
4034         * @see <a href="http://tools.ietf.org/html/rfc6715#page-5">RFC 6715 p.5</a>
4035         */
4036        public Interest addInterest(String interest) {
4037                Interest type = new Interest(interest);
4038                addInterest(type);
4039                return type;
4040        }
4041
4042        /**
4043         * <p>
4044         * Adds an interest.
4045         * </p>
4046         * <p>
4047         * <b>Property name:</b> {@code INTEREST}<br>
4048         * <b>Supported versions:</b> {@code 4.0}
4049         * </p>
4050         * @param altRepresentations the alternative representations of the same
4051         * value. These properties contain the same information, but in different
4052         * forms (such as different languages). See {@link VCardParameters#getAltId
4053         * this description of the ALTID parameter} for more information. Note that
4054         * this method automatically assigns an appropriate ALTID parameter to each
4055         * property.
4056         * @see <a href="http://tools.ietf.org/html/rfc6715#page-5">RFC 6715 p.5</a>
4057         */
4058        public void addInterestAlt(Interest... altRepresentations) {
4059                addPropertyAlt(Interest.class, altRepresentations);
4060        }
4061
4062        /**
4063         * <p>
4064         * Gets the organization directories.
4065         * </p>
4066         * <p>
4067         * <b>Property name:</b> {@code ORG-DIRECTORY}<br>
4068         * <b>Supported versions:</b> {@code 4.0}
4069         * </p>
4070         * @return the organization directory properties (any changes made this list
4071         * will affect the {@link VCard} object and vice versa)
4072         * @see <a href="http://tools.ietf.org/html/rfc6715#page-6">RFC 6715 p.6</a>
4073         */
4074        public List<OrgDirectory> getOrgDirectories() {
4075                return getProperties(OrgDirectory.class);
4076        }
4077
4078        /**
4079         * <p>
4080         * Adds an organization directory.
4081         * </p>
4082         * <p>
4083         * <b>Property name:</b> {@code ORG-DIRECTORY}<br>
4084         * <b>Supported versions:</b> {@code 4.0}
4085         * </p>
4086         * @param orgDirectory the organization directory property to add
4087         * @see <a href="http://tools.ietf.org/html/rfc6715#page-6">RFC 6715 p.6</a>
4088         */
4089        public void addOrgDirectory(OrgDirectory orgDirectory) {
4090                addProperty(orgDirectory);
4091        }
4092
4093        /**
4094         * <p>
4095         * Adds an organization directory.
4096         * </p>
4097         * <p>
4098         * <b>Property name:</b> {@code ORG-DIRECTORY}<br>
4099         * <b>Supported versions:</b> {@code 4.0}
4100         * </p>
4101         * @param orgDirectory the organization directory to add (e.g.
4102         * "http://company.com/staff")
4103         * @return the property object that was created
4104         * @see <a href="http://tools.ietf.org/html/rfc6715#page-6">RFC 6715 p.6</a>
4105         */
4106        public OrgDirectory addOrgDirectory(String orgDirectory) {
4107                OrgDirectory type = new OrgDirectory(orgDirectory);
4108                addOrgDirectory(type);
4109                return type;
4110        }
4111
4112        /**
4113         * <p>
4114         * Adds an organization directory.
4115         * </p>
4116         * <p>
4117         * <b>Property name:</b> {@code ORG-DIRECTORY}<br>
4118         * <b>Supported versions:</b> {@code 4.0}
4119         * </p>
4120         * @param altRepresentations the alternative representations of the same
4121         * value. These properties contain the same information, but in different
4122         * forms (such as different languages). See {@link VCardParameters#getAltId
4123         * this description of the ALTID parameter} for more information. Note that
4124         * this method automatically assigns an appropriate ALTID parameter to each
4125         * property.
4126         * @see <a href="http://tools.ietf.org/html/rfc6715#page-6">RFC 6715 p.6</a>
4127         */
4128        public void addOrgDirectoryAlt(OrgDirectory... altRepresentations) {
4129                addPropertyAlt(OrgDirectory.class, altRepresentations);
4130        }
4131
4132        /**
4133         * Iterates through each of the vCard's properties in no particular order.
4134         * Does not include the "BEGIN", "END", or "VERSION" properties.
4135         * @return the iterator
4136         */
4137        public Iterator<VCardProperty> iterator() {
4138                return properties.values().iterator();
4139        }
4140
4141        /**
4142         * Gets the first property of a given class.
4143         * @param clazz the property class
4144         * @param <T> the property class
4145         * @return the property or null if not found
4146         */
4147        public <T extends VCardProperty> T getProperty(Class<T> clazz) {
4148                return clazz.cast(properties.first(clazz));
4149        }
4150
4151        /**
4152         * Gets all properties of a given class.
4153         * @param clazz the property class
4154         * @param <T> the property class
4155         * @return the properties (any changes made this list will affect the
4156         * {@link VCard} object and vice versa)
4157         */
4158        public <T extends VCardProperty> List<T> getProperties(Class<T> clazz) {
4159                return new VCardPropertyList<T>(clazz);
4160        }
4161
4162        /**
4163         * Gets all properties of a given class, grouping the alternative
4164         * representations of each property together (see:
4165         * {@link VCardParameters#getAltId description of ALTID})
4166         * @param clazz the property class
4167         * @param <T> the property class
4168         * @return the properties (this list is immutable)
4169         */
4170        public <T extends VCardProperty & HasAltId> List<List<T>> getPropertiesAlt(Class<T> clazz) {
4171                List<T> propertiesWithoutAltIds = new ArrayList<T>();
4172                ListMultimap<String, T> propertiesWithAltIds = new ListMultimap<String, T>();
4173                for (T property : getProperties(clazz)) {
4174                        String altId = property.getAltId();
4175                        if (altId == null) {
4176                                propertiesWithoutAltIds.add(property);
4177                        } else {
4178                                propertiesWithAltIds.put(altId, property);
4179                        }
4180                }
4181
4182                int size = propertiesWithoutAltIds.size() + propertiesWithAltIds.size();
4183                List<List<T>> listToReturn = new ArrayList<List<T>>(size);
4184                for (Map.Entry<String, List<T>> entry : propertiesWithAltIds) {
4185                        listToReturn.add(Collections.unmodifiableList(entry.getValue()));
4186                }
4187
4188                //put properties without ALTIDs at the end
4189                for (T property : propertiesWithoutAltIds) {
4190                        List<T> list = new ArrayList<T>(1);
4191                        list.add(property);
4192                        listToReturn.add(Collections.unmodifiableList(list));
4193                }
4194
4195                return Collections.unmodifiableList(listToReturn);
4196        }
4197
4198        /**
4199         * Gets all the properties in this vCard.
4200         * @return the properties (this list is immutable)
4201         */
4202        public Collection<VCardProperty> getProperties() {
4203                return properties.values();
4204        }
4205
4206        /**
4207         * Adds a property.
4208         * @param property the property to add
4209         */
4210        public void addProperty(VCardProperty property) {
4211                properties.put(property.getClass(), property);
4212        }
4213
4214        /**
4215         * Replaces all existing properties of the given property instance's class
4216         * with the given property instance.
4217         * @param property the property
4218         * @return the properties that were replaced (this list is immutable)
4219         */
4220        public List<VCardProperty> setProperty(VCardProperty property) {
4221                return properties.replace(property.getClass(), property);
4222        }
4223
4224        /**
4225         * Replaces all existing properties of the given class with a single
4226         * property instance. If the property instance is null, then all instances
4227         * of that property will be removed.
4228         * @param clazz the property class (e.g. "Note.class")
4229         * @param property the property or null to remove
4230         * @param <T> the property class
4231         * @return the properties that were replaced (this list is immutable)
4232         */
4233        public <T extends VCardProperty> List<T> setProperty(Class<T> clazz, T property) {
4234                List<VCardProperty> replaced = properties.replace(clazz, property);
4235                return castList(replaced, clazz);
4236        }
4237
4238        /**
4239         * Removes a property instance from the vCard.
4240         * @param property the property to remove
4241         * @return true if it was removed, false if it wasn't found
4242         */
4243        public boolean removeProperty(VCardProperty property) {
4244                return properties.remove(property.getClass(), property);
4245        }
4246
4247        /**
4248         * Removes all properties of a given class.
4249         * @param clazz the class of the properties to remove (e.g. "Note.class")
4250         * @param <T> the property class
4251         * @return the properties that were removed (this list is immutable)
4252         */
4253        public <T extends VCardProperty> List<T> removeProperties(Class<T> clazz) {
4254                List<VCardProperty> removed = properties.removeAll(clazz);
4255                return castList(removed, clazz);
4256        }
4257
4258        /**
4259         * Gets the first extended property with a given name.
4260         * @param name the property name (e.g. "X-ALT-DESC")
4261         * @return the property or null if none were found
4262         */
4263        public RawProperty getExtendedProperty(String name) {
4264                for (RawProperty raw : getExtendedProperties()) {
4265                        if (raw.getPropertyName().equalsIgnoreCase(name)) {
4266                                return raw;
4267                        }
4268                }
4269                return null;
4270        }
4271
4272        /**
4273         * Gets all extended properties with a given name.
4274         * @param name the property name (e.g. "X-ALT-DESC")
4275         * @return the properties (this list is immutable)
4276         */
4277        public List<RawProperty> getExtendedProperties(String name) {
4278                List<RawProperty> properties = new ArrayList<RawProperty>();
4279
4280                for (RawProperty raw : getExtendedProperties()) {
4281                        if (raw.getPropertyName().equalsIgnoreCase(name)) {
4282                                properties.add(raw);
4283                        }
4284                }
4285
4286                return Collections.unmodifiableList(properties);
4287        }
4288
4289        /**
4290         * Gets all extended properties.
4291         * @return the properties (any changes made this list will affect the
4292         * {@link VCard} object and vice versa)
4293         */
4294        public List<RawProperty> getExtendedProperties() {
4295                return getProperties(RawProperty.class);
4296        }
4297
4298        /**
4299         * Adds an extended property.
4300         * @param name the property name (e.g. "X-ALT-DESC")
4301         * @param value the property value
4302         * @return the property object that was created
4303         */
4304        public RawProperty addExtendedProperty(String name, String value) {
4305                RawProperty raw = new RawProperty(name, value);
4306                addProperty(raw);
4307                return raw;
4308        }
4309
4310        /**
4311         * Adds an extended property.
4312         * @param name the property name (e.g. "X-ALT-DESC")
4313         * @param value the property value
4314         * @param dataType the property value's data type
4315         * @return the property object that was created
4316         */
4317        public RawProperty addExtendedProperty(String name, String value, VCardDataType dataType) {
4318                RawProperty raw = new RawProperty(name, value, dataType);
4319                addProperty(raw);
4320                return raw;
4321        }
4322
4323        /**
4324         * Replaces all existing extended properties with the given name with a
4325         * single property instance.
4326         * @param name the property name (e.g. "X-ALT-DESC")
4327         * @param value the property value
4328         * @return the property object that was created
4329         */
4330        public RawProperty setExtendedProperty(String name, String value) {
4331                removeExtendedProperty(name);
4332                return addExtendedProperty(name, value);
4333        }
4334
4335        /**
4336         * Replaces all existing extended properties with the given name with a
4337         * single property instance.
4338         * @param name the property name (e.g. "X-ALT-DESC")
4339         * @param value the property value
4340         * @param dataType the property value's data type
4341         * @return the property object that was created
4342         */
4343        public RawProperty setExtendedProperty(String name, String value, VCardDataType dataType) {
4344                removeExtendedProperty(name);
4345                return addExtendedProperty(name, value, dataType);
4346        }
4347
4348        /**
4349         * Removes all extended properties that have the given name.
4350         * @param name the component name (e.g. "X-ALT-DESC")
4351         * @return the properties that were removed (this list is immutable)
4352         */
4353        public List<RawProperty> removeExtendedProperty(String name) {
4354                List<RawProperty> all = getExtendedProperties();
4355                List<RawProperty> toRemove = new ArrayList<RawProperty>();
4356                for (RawProperty property : all) {
4357                        if (property.getPropertyName().equalsIgnoreCase(name)) {
4358                                toRemove.add(property);
4359                        }
4360                }
4361
4362                all.removeAll(toRemove);
4363                return Collections.unmodifiableList(toRemove);
4364        }
4365
4366        /**
4367         * Adds a property in the form of a collection of alternative
4368         * representations. This method will generate a unique ALTID parameter value
4369         * and assign it to each of the property instances (see:
4370         * {@link VCardParameters#getAltId description of ALTID}).
4371         * @param propertyClass the property class
4372         * @param altRepresentations the alternative representations of the property
4373         * to add
4374         * @param <T> the property class
4375         */
4376        public <T extends VCardProperty & HasAltId> void addPropertyAlt(Class<T> propertyClass, T... altRepresentations) {
4377                addPropertyAlt(propertyClass, Arrays.asList(altRepresentations));
4378        }
4379
4380        /**
4381         * Adds a property in the form of a collection of alternative
4382         * representations. This method will generate a unique ALTID parameter value
4383         * and assign it to each of the property instances (see:
4384         * {@link VCardParameters#getAltId description of ALTID}).
4385         * @param propertyClass the property class
4386         * @param altRepresentations the alternative representations of the property
4387         * to add
4388         * @param <T> the property class
4389         */
4390        public <T extends VCardProperty & HasAltId> void addPropertyAlt(Class<T> propertyClass, Collection<T> altRepresentations) {
4391                String altId = generateAltId(getProperties(propertyClass));
4392                for (T property : altRepresentations) {
4393                        property.setAltId(altId);
4394                        addProperty(property);
4395                }
4396        }
4397
4398        /**
4399         * Sets a property in the form of a collection of alternative
4400         * representations. This method will generate a unique ALTID parameter value
4401         * and assign it to each of the property instances (see:
4402         * {@link VCardParameters#getAltId description of ALTID}).
4403         * @param propertyClass the property class
4404         * @param altRepresentations the alternative representations of the property
4405         * to add
4406         * @param <T> the property class
4407         * @return the properties that were replaced (this list is immutable)
4408         */
4409        public <T extends VCardProperty & HasAltId> List<T> setPropertyAlt(Class<T> propertyClass, T... altRepresentations) {
4410                return setPropertyAlt(propertyClass, Arrays.asList(altRepresentations));
4411        }
4412
4413        /**
4414         * Sets a property in the form of a collection of alternative
4415         * representations. This method will generate a unique ALTID parameter value
4416         * and assign it to each of the property instances (see:
4417         * {@link VCardParameters#getAltId description of ALTID}).
4418         * @param propertyClass the property class
4419         * @param altRepresentations the alternative representations of the property
4420         * to add
4421         * @param <T> the property class
4422         * @return the properties that were replaced (this list is immutable)
4423         */
4424        public <T extends VCardProperty & HasAltId> List<T> setPropertyAlt(Class<T> propertyClass, Collection<T> altRepresentations) {
4425                List<T> removed = removeProperties(propertyClass);
4426                addPropertyAlt(propertyClass, altRepresentations);
4427                return removed;
4428        }
4429
4430        /**
4431         * Casts all objects in the given list to the given class, adding the casted
4432         * objects to a new list.
4433         * @param list the list to cast
4434         * @param castTo the class to cast to
4435         * @param <T> the class to cast to
4436         * @return the new list (this list is immutable)
4437         */
4438        private static <T> List<T> castList(List<?> list, Class<T> castTo) {
4439                List<T> casted = new ArrayList<T>(list.size());
4440                for (Object object : list) {
4441                        casted.add(castTo.cast(object));
4442                }
4443                return Collections.unmodifiableList(casted);
4444        }
4445
4446        /**
4447         * Checks this vCard for data consistency problems or deviations from the
4448         * spec. These problems will not prevent the vCard from being written to a
4449         * data stream, but may prevent it from being parsed correctly by the
4450         * consuming application. These problems can largely be avoided by reading
4451         * the Javadocs of the property classes, or by being familiar with the vCard
4452         * standard.
4453         * @param version the version to check the vCard against (use
4454         * {@link VCardVersion#V4_0} for xCard and jCard)
4455         * @return the validation warnings
4456         */
4457        public ValidationWarnings validate(VCardVersion version) {
4458                ValidationWarnings warnings = new ValidationWarnings();
4459
4460                //validate overall vCard object
4461                if (getStructuredName() == null && (version == VCardVersion.V2_1 || version == VCardVersion.V3_0)) {
4462                        warnings.add(null, new ValidationWarning(0));
4463                }
4464                if (getFormattedName() == null && (version == VCardVersion.V3_0 || version == VCardVersion.V4_0)) {
4465                        warnings.add(null, new ValidationWarning(1));
4466                }
4467
4468                //validate properties
4469                for (VCardProperty property : this) {
4470                        List<ValidationWarning> propWarnings = property.validate(version, this);
4471                        if (!propWarnings.isEmpty()) {
4472                                warnings.add(property, propWarnings);
4473                        }
4474                }
4475
4476                return warnings;
4477        }
4478
4479        @Override
4480        public String toString() {
4481                StringBuilder sb = new StringBuilder();
4482                sb.append("version=").append(version);
4483                for (VCardProperty property : properties.values()) {
4484                        sb.append(StringUtils.NEWLINE).append(property);
4485                }
4486                return sb.toString();
4487        }
4488
4489        @Override
4490        public int hashCode() {
4491                final int prime = 31;
4492                int result = 1;
4493
4494                result = prime * result + ((version == null) ? 0 : version.hashCode());
4495
4496                int propertiesHash = 1;
4497                for (VCardProperty property : properties.values()) {
4498                        propertiesHash += property.hashCode();
4499                }
4500                result = prime * result + propertiesHash;
4501
4502                return result;
4503        }
4504
4505        @Override
4506        public boolean equals(Object obj) {
4507                if (this == obj) return true;
4508                if (obj == null) return false;
4509                if (getClass() != obj.getClass()) return false;
4510                VCard other = (VCard) obj;
4511                if (version != other.version) return false;
4512                if (properties.size() != other.properties.size()) return false;
4513
4514                for (Map.Entry<Class<? extends VCardProperty>, List<VCardProperty>> entry : properties) {
4515                        Class<? extends VCardProperty> key = entry.getKey();
4516                        List<VCardProperty> value = entry.getValue();
4517                        List<VCardProperty> otherValue = other.properties.get(key);
4518
4519                        if (value.size() != otherValue.size()) {
4520                                return false;
4521                        }
4522
4523                        List<VCardProperty> otherValueCopy = new ArrayList<VCardProperty>(otherValue);
4524                        for (VCardProperty property : value) {
4525                                if (!otherValueCopy.remove(property)) {
4526                                        return false;
4527                                }
4528                        }
4529                }
4530
4531                return true;
4532        }
4533
4534        /**
4535         * Generates a unique ALTID parameter value.
4536         * @param properties the collection of properties under which the ALTID must
4537         * be unique
4538         * @param <T> the property class
4539         * @return a unique ALTID
4540         */
4541        static <T extends HasAltId> String generateAltId(Collection<T> properties) {
4542                Set<String> altIds = new HashSet<String>();
4543                for (T property : properties) {
4544                        String altId = property.getAltId();
4545                        if (altId != null) {
4546                                altIds.add(altId);
4547                        }
4548                }
4549
4550                int altId = 1;
4551                while (altIds.contains(Integer.toString(altId))) {
4552                        altId++;
4553                }
4554                return Integer.toString(altId);
4555        }
4556
4557        /**
4558         * <p>
4559         * A list that automatically casts {@link VCardProperty} instances stored in
4560         * this {@link VCard} to a given property class.
4561         * </p>
4562         * <p>
4563         * This list is backed by the {@link VCard} object. Any changes made to the
4564         * list will affect the {@link VCard} object and vice versa.
4565         * </p>
4566         * @param <T> the property class
4567         */
4568        private class VCardPropertyList<T extends VCardProperty> extends AbstractList<T> {
4569                protected final Class<T> propertyClass;
4570                protected final List<VCardProperty> properties;
4571
4572                /**
4573                 * @param propertyClass the property class
4574                 */
4575                public VCardPropertyList(Class<T> propertyClass) {
4576                        this.propertyClass = propertyClass;
4577                        properties = VCard.this.properties.get(propertyClass);
4578                }
4579
4580                @Override
4581                public void add(int index, T value) {
4582                        properties.add(index, value);
4583                }
4584
4585                @Override
4586                public T remove(int index) {
4587                        VCardProperty removed = properties.remove(index);
4588                        return cast(removed);
4589                }
4590
4591                @Override
4592                public T get(int index) {
4593                        VCardProperty property = properties.get(index);
4594                        return cast(property);
4595                }
4596
4597                @Override
4598                public T set(int index, T value) {
4599                        VCardProperty replaced = properties.set(index, value);
4600                        return cast(replaced);
4601                }
4602
4603                @Override
4604                public int size() {
4605                        return properties.size();
4606                }
4607
4608                private T cast(VCardProperty value) {
4609                        return propertyClass.cast(value);
4610                }
4611        }
4612}