1917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/*
2917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Copyright (C) 2007 The Android Open Source Project
3917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *
4917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Licensed under the Apache License, Version 2.0 (the "License");
5917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * you may not use this file except in compliance with the License.
6917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * You may obtain a copy of the License at
7917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *
8917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *      http://www.apache.org/licenses/LICENSE-2.0
9917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *
10917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Unless required by applicable law or agreed to in writing, software
11917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * distributed under the License is distributed on an "AS IS" BASIS,
12917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * See the License for the specific language governing permissions and
14917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * limitations under the License.
15917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */
16917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
17917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpackage com.android.dexgen.rop.annotation;
18917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
19917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.cst.Constant;
20917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.cst.CstAnnotation;
21917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.cst.CstFieldRef;
22917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.cst.CstLiteralBits;
23917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.cst.CstMethodRef;
24917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.cst.CstNat;
25917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.cst.CstType;
26917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.cst.CstUtf8;
27917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.cst.TypedConstant;
28917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.util.Hex;
29917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.util.MutabilityControl;
30917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.util.ToHuman;
31917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
32917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport java.util.Collection;
33917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport java.util.Collections;
34917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport java.util.Iterator;
35917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport java.util.TreeMap;
36917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
37917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/**
38917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * An annotation on an element of a class. Annotations have an
39917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * associated type and additionally consist of a set of (name, value)
40917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * pairs, where the names are unique.
41917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */
42917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpublic final class Annotation extends MutabilityControl
43917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        implements Comparable<Annotation>, ToHuman {
44917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@code non-null;} type of the annotation */
45917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private final CstType type;
46917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
47917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@code non-null;} the visibility of the annotation */
48917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private final AnnotationVisibility visibility;
49917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
50917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@code non-null;} map from names to {@link NameValuePair} instances */
51917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private final TreeMap<CstUtf8, NameValuePair> elements;
52917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
53917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
54917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Construct an instance. It initially contains no elements.
55917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
56917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param type {@code non-null;} type of the annotation
57917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param visibility {@code non-null;} the visibility of the annotation
58917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
59917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public Annotation(CstType type, AnnotationVisibility visibility) {
60917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        if (type == null) {
61917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            throw new NullPointerException("type == null");
62917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
63917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
64917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        if (visibility == null) {
65917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            throw new NullPointerException("visibility == null");
66917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
67917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
68917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        this.type = type;
69917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        this.visibility = visibility;
70917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        this.elements = new TreeMap<CstUtf8, NameValuePair>();
71917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
72917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
73917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@inheritDoc} */
74917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    @Override
75917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public boolean equals(Object other) {
76917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        if (! (other instanceof Annotation)) {
77917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            return false;
78917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
79917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
80917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        Annotation otherAnnotation = (Annotation) other;
81917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
82917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        if (! (type.equals(otherAnnotation.type)
83917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                        && (visibility == otherAnnotation.visibility))) {
84917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            return false;
85917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
86917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
87917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return elements.equals(otherAnnotation.elements);
88917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
89917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
90917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@inheritDoc} */
91917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public int hashCode() {
92917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int hash = type.hashCode();
93917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        hash = (hash * 31) + elements.hashCode();
94917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        hash = (hash * 31) + visibility.hashCode();
95917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return hash;
96917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
97917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
98917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@inheritDoc} */
99917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public int compareTo(Annotation other) {
100917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int result = type.compareTo(other.type);
101917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
102917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        if (result != 0) {
103917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            return result;
104917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
105917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
106917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        result = visibility.compareTo(other.visibility);
107917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
108917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        if (result != 0) {
109917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            return result;
110917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
111917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
112917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        Iterator<NameValuePair> thisIter = elements.values().iterator();
113917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        Iterator<NameValuePair> otherIter = other.elements.values().iterator();
114917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
115917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        while (thisIter.hasNext() && otherIter.hasNext()) {
116917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            NameValuePair thisOne = thisIter.next();
117917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            NameValuePair otherOne = otherIter.next();
118917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
119917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            result = thisOne.compareTo(otherOne);
120917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            if (result != 0) {
121917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                return result;
122917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            }
123917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
124917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
125917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        if (thisIter.hasNext()) {
126917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            return 1;
127917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        } else if (otherIter.hasNext()) {
128917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            return -1;
129917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
130917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
131917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return 0;
132917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
133917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
134917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@inheritDoc} */
135917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    @Override
136917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public String toString() {
137917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return toHuman();
138917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
139917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
140917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@inheritDoc} */
141917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public String toHuman() {
142917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        StringBuilder sb = new StringBuilder();
143917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
144917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        sb.append(visibility.toHuman());
145917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        sb.append("-annotation ");
146917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        sb.append(type.toHuman());
147917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        sb.append(" {");
148917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
149917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        boolean first = true;
150917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        for (NameValuePair pair : elements.values()) {
151917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            if (first) {
152917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                first = false;
153917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            } else {
154917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                sb.append(", ");
155917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            }
156917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            sb.append(pair.getName().toHuman());
157917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            sb.append(": ");
158917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            sb.append(pair.getValue().toHuman());
159917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
160917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
161917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        sb.append("}");
162917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return sb.toString();
163917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
164917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
165917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
166917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Gets the type of this instance.
167917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
168917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} the type
169917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
170917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public CstType getType() {
171917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return type;
172917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
173917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
174917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
175917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Gets the visibility of this instance.
176917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
177917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} the visibility
178917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
179917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public AnnotationVisibility getVisibility() {
180917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return visibility;
181917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
182917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
183917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
184917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Put an element into the set of (name, value) pairs for this instance.
185917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * If there is a preexisting element with the same name, it will be
186917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * replaced by this method.
187917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
188917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param pair {@code non-null;} the (name, value) pair to place into this instance
189917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
190917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public void put(NameValuePair pair) {
191917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        throwIfImmutable();
192917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
193917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        if (pair == null) {
194917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            throw new NullPointerException("pair == null");
195917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
196917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
197917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        elements.put(pair.getName(), pair);
198917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
199917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
200917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
201917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Add an element to the set of (name, value) pairs for this instance.
202917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * It is an error to call this method if there is a preexisting element
203917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * with the same name.
204917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
205917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param pair {@code non-null;} the (name, value) pair to add to this instance
206917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
207917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public void add(NameValuePair pair) {
208917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        throwIfImmutable();
209917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
210917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        if (pair == null) {
211917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            throw new NullPointerException("pair == null");
212917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
213917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
214917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        CstUtf8 name = pair.getName();
215917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
216917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        if (elements.get(name) != null) {
217917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            throw new IllegalArgumentException("name already added: " + name);
218917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
219917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
220917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        elements.put(name, pair);
221917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
222917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
223917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
224917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Gets the set of name-value pairs contained in this instance. The
225917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * result is always unmodifiable.
226917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
227917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} the set of name-value pairs
228917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
229917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public Collection<NameValuePair> getNameValuePairs() {
230917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return Collections.unmodifiableCollection(elements.values());
231917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
232917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul}
233