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