1 module hunt.security.Subject;
2 
3 import hunt.security.Principal;
4 
5 import hunt.collection;
6 
7 /**
8  * <p> A {@code Subject} represents a grouping of related information
9  * for a single entity, such as a person.
10  * Such information includes the Subject's identities as well as
11  * its security-related attributes
12  * (passwords and cryptographic keys, for example).
13  *
14  * <p> Subjects may potentially have multiple identities.
15  * Each identity is represented as a {@code Principal}
16  * within the {@code Subject}.  Principals simply bind names to a
17  * {@code Subject}.  For example, a {@code Subject} that happens
18  * to be a person, Alice, might have two Principals:
19  * one which binds "Alice Bar", the name on her driver license,
20  * to the {@code Subject}, and another which binds,
21  * "999-99-9999", the number on her student identification card,
22  * to the {@code Subject}.  Both Principals refer to the same
23  * {@code Subject} even though each has a different name.
24  *
25  * <p> A {@code Subject} may also own security-related attributes,
26  * which are referred to as credentials.
27  * Sensitive credentials that require special protection, such as
28  * private cryptographic keys, are stored within a private credential
29  * {@code Set}.  Credentials intended to be shared, such as
30  * key certificates or Kerberos server tickets are stored
31  * within a credential {@code Set}.  Different permissions
32  * are required to access and modify the different credential Sets.
33  *
34  * <p> To retrieve all the Principals associated with a {@code Subject},
35  * invoke the {@code getPrincipals} method.  To retrieve
36  * all the or private credentials belonging to a {@code Subject},
37  * invoke the {@code getPublicCredentials} method or
38  * {@code getPrivateCredentials} method, respectively.
39  * To modify the returned {@code Set} of Principals and credentials,
40  * use the methods defined in the {@code Set} class.
41  * For example:
42  * <pre>
43  *      Subject subject;
44  *      Principal principal;
45  *      Object credential;
46  *
47  *      // add a Principal and credential to the Subject
48  *      subject.getPrincipals().add(principal);
49  *      subject.getPublicCredentials().add(credential);
50  * </pre>
51  *
52  * <p> This {@code Subject} class implements {@code Serializable}.
53  * While the Principals associated with the {@code Subject} are serialized,
54  * the credentials associated with the {@code Subject} are not.
55  * Note that the {@code java.security.Principal} class
56  * does not implement {@code Serializable}.  Therefore all concrete
57  * {@code Principal} implementations associated with Subjects
58  * must implement {@code Serializable}.
59  *
60  * @see java.security.Principal
61  * @see java.security.DomainCombiner
62  */
63 class Subject {
64 
65     private enum serialVersionUID = -8308522755600156056L;
66 
67     /**
68      * A {@code Set} that provides a view of all of this
69      * Subject's Principals
70      *
71      * <p>
72      *
73      * @serial Each element in this set is a
74      *          {@code java.security.Principal}.
75      *          The set is a {@code Subject.SecureSet}.
76      */
77     Set!Principal principals;
78 
79     /**
80      * Sets that provide a view of all of this
81      * Subject's Credentials
82      */
83     Set!Object pubCredentials;
84     Set!Object privCredentials;
85 
86     // /**
87     //  * Whether this Subject is read-only
88     //  *
89     //  * @serial
90     //  */
91     // private bool readOnly = false;
92 
93     // private enum int PRINCIPAL_SET = 1;
94     // private enum int PUB_CREDENTIAL_SET = 2;
95     // private enum int PRIV_CREDENTIAL_SET = 3;
96 
97     // // private __gshared ProtectionDomain[] NULL_PD_ARRAY;
98         
99     // // shared static this()
100     // // {
101     // //     NULL_PD_ARRAY = new ProtectionDomain[0];
102     // // }
103 
104     // /**
105     //  * Create an instance of a {@code Subject}
106     //  * with an empty {@code Set} of Principals and empty
107     //  * Sets of and private credentials.
108     //  *
109     //  * <p> The newly constructed Sets check whether this {@code Subject}
110     //  * has been set read-only before permitting subsequent modifications.
111     //  * The newly created Sets also prevent illegal modifications
112     //  * by ensuring that callers have sufficient permissions.
113     //  *
114     //  * <p> To modify the Principals Set, the caller must have
115     //  * {@code AuthPermission("modifyPrincipals")}.
116     //  * To modify the credential Set, the caller must have
117     //  * {@code AuthPermission("modifyPublicCredentials")}.
118     //  * To modify the private credential Set, the caller must have
119     //  * {@code AuthPermission("modifyPrivateCredentials")}.
120     //  */
121     // this() {
122 
123     //     this.principals = Collections.synchronizedSet
124     //                     (new SecureSet!Principal(this, PRINCIPAL_SET));
125     //     this.pubCredentials = Collections.synchronizedSet
126     //                     (new SecureSet!Object(this, PUB_CREDENTIAL_SET));
127     //     this.privCredentials = Collections.synchronizedSet
128     //                     (new SecureSet!Object(this, PRIV_CREDENTIAL_SET));
129     // }
130 
131     // /**
132     //  * Create an instance of a {@code Subject} with
133     //  * Principals and credentials.
134     //  *
135     //  * <p> The Principals and credentials from the specified Sets
136     //  * are copied into newly constructed Sets.
137     //  * These newly created Sets check whether this {@code Subject}
138     //  * has been set read-only before permitting subsequent modifications.
139     //  * The newly created Sets also prevent illegal modifications
140     //  * by ensuring that callers have sufficient permissions.
141     //  *
142     //  * <p> To modify the Principals Set, the caller must have
143     //  * {@code AuthPermission("modifyPrincipals")}.
144     //  * To modify the credential Set, the caller must have
145     //  * {@code AuthPermission("modifyPublicCredentials")}.
146     //  * To modify the private credential Set, the caller must have
147     //  * {@code AuthPermission("modifyPrivateCredentials")}.
148     //  * <p>
149     //  *
150     //  * @param readOnly true if the {@code Subject} is to be read-only,
151     //  *          and false otherwise. <p>
152     //  *
153     //  * @param principals the {@code Set} of Principals
154     //  *          to be associated with this {@code Subject}. <p>
155     //  *
156     //  * @param pubCredentials the {@code Set} of credentials
157     //  *          to be associated with this {@code Subject}. <p>
158     //  *
159     //  * @param privCredentials the {@code Set} of private credentials
160     //  *          to be associated with this {@code Subject}.
161     //  *
162     //  * @exception NullPointerException if the specified
163     //  *          {@code principals}, {@code pubCredentials},
164     //  *          or {@code privCredentials} are {@code null}.
165     //  */
166     // this(bool readOnly, Set<? : Principal> principals,
167     //                Set<?> pubCredentials, Set<?> privCredentials)
168     // {
169 
170     //     if (principals is null ||
171     //         pubCredentials is null ||
172     //         privCredentials is null)
173     //         throw new NullPointerException
174     //             (ResourcesMgr.getString("invalid.null.input.s."));
175 
176     //     this.principals = Collections.synchronizedSet(new SecureSet!Principal
177     //                             (this, PRINCIPAL_SET, principals));
178     //     this.pubCredentials = Collections.synchronizedSet(new SecureSet!Object
179     //                             (this, PUB_CREDENTIAL_SET, pubCredentials));
180     //     this.privCredentials = Collections.synchronizedSet(new SecureSet!Object
181     //                             (this, PRIV_CREDENTIAL_SET, privCredentials));
182     //     this.readOnly = readOnly;
183     // }
184 
185     // /**
186     //  * Set this {@code Subject} to be read-only.
187     //  *
188     //  * <p> Modifications (additions and removals) to this Subject's
189     //  * {@code Principal} {@code Set} and
190     //  * credential Sets will be disallowed.
191     //  * The {@code destroy} operation on this Subject's credentials will
192     //  * still be permitted.
193     //  *
194     //  * <p> Subsequent attempts to modify the Subject's {@code Principal}
195     //  * and credential Sets will result in an
196     //  * {@code IllegalStateException} being thrown.
197     //  * Also, once a {@code Subject} is read-only,
198     //  * it can not be reset to being writable again.
199     //  *
200     //  * <p>
201     //  *
202     //  * @exception SecurityException if the caller does not have permission
203     //  *          to set this {@code Subject} to be read-only.
204     //  */
205     // void setReadOnly() {
206     //     // java.lang.SecurityManager sm = System.getSecurityManager();
207     //     // if (sm !is null) {
208     //     //     sm.checkPermission(AuthPermissionHolder.SET_READ_ONLY_PERMISSION);
209     //     // }
210 
211     //     this.readOnly = true;
212     // }
213 
214     // /**
215     //  * Query whether this {@code Subject} is read-only.
216     //  *
217     //  * <p>
218     //  *
219     //  * @return true if this {@code Subject} is read-only, false otherwise.
220     //  */
221     // bool isReadOnly() {
222     //     return this.readOnly;
223     // }
224 
225     // /**
226     //  * Get the {@code Subject} associated with the provided
227     //  * {@code AccessControlContext}.
228     //  *
229     //  * <p> The {@code AccessControlContext} may contain many
230     //  * Subjects (from nested {@code doAs} calls).
231     //  * In this situation, the most recent {@code Subject} associated
232     //  * with the {@code AccessControlContext} is returned.
233     //  *
234     //  * <p>
235     //  *
236     //  * @param  acc the {@code AccessControlContext} from which to retrieve
237     //  *          the {@code Subject}.
238     //  *
239     //  * @return  the {@code Subject} associated with the provided
240     //  *          {@code AccessControlContext}, or {@code null}
241     //  *          if no {@code Subject} is associated
242     //  *          with the provided {@code AccessControlContext}.
243     //  *
244     //  * @exception SecurityException if the caller does not have permission
245     //  *          to get the {@code Subject}. <p>
246     //  *
247     //  * @exception NullPointerException if the provided
248     //  *          {@code AccessControlContext} is {@code null}.
249     //  */
250     // static Subject getSubject(AccessControlContext acc) {
251 
252     //     java.lang.SecurityManager sm = System.getSecurityManager();
253     //     if (sm !is null) {
254     //         sm.checkPermission(AuthPermissionHolder.GET_SUBJECT_PERMISSION);
255     //     }
256 
257     //     if (acc is null) {
258     //         throw new NullPointerException(ResourcesMgr.getString
259     //             ("invalid.null.AccessControlContext.provided"));
260     //     }
261 
262     //     // return the Subject from the DomainCombiner of the provided context
263     //     return AccessController.doPrivileged
264     //         (new java.security.PrivilegedAction<Subject>() {
265     //         Subject run() {
266     //             DomainCombiner dc = acc.getDomainCombiner();
267     //             if (!(dc instanceof SubjectDomainCombiner))
268     //                 return null;
269     //             SubjectDomainCombiner sdc = (SubjectDomainCombiner)dc;
270     //             return sdc.getSubject();
271     //         }
272     //     });
273     // }
274 
275     // /**
276     //  * Perform work as a particular {@code Subject}.
277     //  *
278     //  * <p> This method first retrieves the current Thread's
279     //  * {@code AccessControlContext} via
280     //  * {@code AccessController.getContext},
281     //  * and then instantiates a new {@code AccessControlContext}
282     //  * using the retrieved context along with a new
283     //  * {@code SubjectDomainCombiner} (constructed using
284     //  * the provided {@code Subject}).
285     //  * Finally, this method invokes {@code AccessController.doPrivileged},
286     //  * passing it the provided {@code PrivilegedAction},
287     //  * as well as the newly constructed {@code AccessControlContext}.
288     //  *
289     //  * <p>
290     //  *
291     //  * @param subject the {@code Subject} that the specified
292     //  *                  {@code action} will run as.  This parameter
293     //  *                  may be {@code null}. <p>
294     //  *
295     //  * @param <T> the type of the value returned by the PrivilegedAction's
296     //  *                  {@code run} method.
297     //  *
298     //  * @param action the code to be run as the specified
299     //  *                  {@code Subject}. <p>
300     //  *
301     //  * @return the value returned by the PrivilegedAction's
302     //  *                  {@code run} method.
303     //  *
304     //  * @exception NullPointerException if the {@code PrivilegedAction}
305     //  *                  is {@code null}. <p>
306     //  *
307     //  * @exception SecurityException if the caller does not have permission
308     //  *                  to invoke this method.
309     //  */
310     // static <T> T doAs(Subject subject,
311     //                     java.security.PrivilegedAction<T> action) {
312 
313     //     java.lang.SecurityManager sm = System.getSecurityManager();
314     //     if (sm !is null) {
315     //         sm.checkPermission(AuthPermissionHolder.DO_AS_PERMISSION);
316     //     }
317     //     if (action is null)
318     //         throw new NullPointerException
319     //             (ResourcesMgr.getString("invalid.null.action.provided"));
320 
321     //     // set up the new Subject-based AccessControlContext
322     //     // for doPrivileged
323     //     AccessControlContext currentAcc = AccessController.getContext();
324 
325     //     // call doPrivileged and push this new context on the stack
326     //     return java.security.AccessController.doPrivileged
327     //                                     (action,
328     //                                     createContext(subject, currentAcc));
329     // }
330 
331     // /**
332     //  * Perform work as a particular {@code Subject}.
333     //  *
334     //  * <p> This method first retrieves the current Thread's
335     //  * {@code AccessControlContext} via
336     //  * {@code AccessController.getContext},
337     //  * and then instantiates a new {@code AccessControlContext}
338     //  * using the retrieved context along with a new
339     //  * {@code SubjectDomainCombiner} (constructed using
340     //  * the provided {@code Subject}).
341     //  * Finally, this method invokes {@code AccessController.doPrivileged},
342     //  * passing it the provided {@code PrivilegedExceptionAction},
343     //  * as well as the newly constructed {@code AccessControlContext}.
344     //  *
345     //  * <p>
346     //  *
347     //  * @param subject the {@code Subject} that the specified
348     //  *                  {@code action} will run as.  This parameter
349     //  *                  may be {@code null}. <p>
350     //  *
351     //  * @param <T> the type of the value returned by the
352     //  *                  PrivilegedExceptionAction's {@code run} method.
353     //  *
354     //  * @param action the code to be run as the specified
355     //  *                  {@code Subject}. <p>
356     //  *
357     //  * @return the value returned by the
358     //  *                  PrivilegedExceptionAction's {@code run} method.
359     //  *
360     //  * @exception PrivilegedActionException if the
361     //  *                  {@code PrivilegedExceptionAction.run}
362     //  *                  method throws a checked exception. <p>
363     //  *
364     //  * @exception NullPointerException if the specified
365     //  *                  {@code PrivilegedExceptionAction} is
366     //  *                  {@code null}. <p>
367     //  *
368     //  * @exception SecurityException if the caller does not have permission
369     //  *                  to invoke this method.
370     //  */
371     // static <T> T doAs(Subject subject,
372     //                     java.security.PrivilegedExceptionAction<T> action)
373     //                     throws java.security.PrivilegedActionException {
374 
375     //     java.lang.SecurityManager sm = System.getSecurityManager();
376     //     if (sm !is null) {
377     //         sm.checkPermission(AuthPermissionHolder.DO_AS_PERMISSION);
378     //     }
379 
380     //     if (action is null)
381     //         throw new NullPointerException
382     //             (ResourcesMgr.getString("invalid.null.action.provided"));
383 
384     //     // set up the new Subject-based AccessControlContext for doPrivileged
385     //     AccessControlContext currentAcc = AccessController.getContext();
386 
387     //     // call doPrivileged and push this new context on the stack
388     //     return java.security.AccessController.doPrivileged
389     //                                     (action,
390     //                                     createContext(subject, currentAcc));
391     // }
392 
393     // /**
394     //  * Perform privileged work as a particular {@code Subject}.
395     //  *
396     //  * <p> This method behaves exactly as {@code Subject.doAs},
397     //  * except that instead of retrieving the current Thread's
398     //  * {@code AccessControlContext}, it uses the provided
399     //  * {@code AccessControlContext}.  If the provided
400     //  * {@code AccessControlContext} is {@code null},
401     //  * this method instantiates a new {@code AccessControlContext}
402     //  * with an empty collection of ProtectionDomains.
403     //  *
404     //  * <p>
405     //  *
406     //  * @param subject the {@code Subject} that the specified
407     //  *                  {@code action} will run as.  This parameter
408     //  *                  may be {@code null}. <p>
409     //  *
410     //  * @param <T> the type of the value returned by the PrivilegedAction's
411     //  *                  {@code run} method.
412     //  *
413     //  * @param action the code to be run as the specified
414     //  *                  {@code Subject}. <p>
415     //  *
416     //  * @param acc the {@code AccessControlContext} to be tied to the
417     //  *                  specified <i>subject</i> and <i>action</i>. <p>
418     //  *
419     //  * @return the value returned by the PrivilegedAction's
420     //  *                  {@code run} method.
421     //  *
422     //  * @exception NullPointerException if the {@code PrivilegedAction}
423     //  *                  is {@code null}. <p>
424     //  *
425     //  * @exception SecurityException if the caller does not have permission
426     //  *                  to invoke this method.
427     //  */
428     // static <T> T doAsPrivileged(Subject subject,
429     //                     java.security.PrivilegedAction<T> action,
430     //                     java.security.AccessControlContext acc) {
431 
432     //     java.lang.SecurityManager sm = System.getSecurityManager();
433     //     if (sm !is null) {
434     //         sm.checkPermission(AuthPermissionHolder.DO_AS_PRIVILEGED_PERMISSION);
435     //     }
436 
437     //     if (action is null)
438     //         throw new NullPointerException
439     //             (ResourcesMgr.getString("invalid.null.action.provided"));
440 
441     //     // set up the new Subject-based AccessControlContext
442     //     // for doPrivileged
443     //     AccessControlContext callerAcc =
444     //             (acc is null ?
445     //             new AccessControlContext(NULL_PD_ARRAY) :
446     //             acc);
447 
448     //     // call doPrivileged and push this new context on the stack
449     //     return java.security.AccessController.doPrivileged
450     //                                     (action,
451     //                                     createContext(subject, callerAcc));
452     // }
453 
454     // /**
455     //  * Perform privileged work as a particular {@code Subject}.
456     //  *
457     //  * <p> This method behaves exactly as {@code Subject.doAs},
458     //  * except that instead of retrieving the current Thread's
459     //  * {@code AccessControlContext}, it uses the provided
460     //  * {@code AccessControlContext}.  If the provided
461     //  * {@code AccessControlContext} is {@code null},
462     //  * this method instantiates a new {@code AccessControlContext}
463     //  * with an empty collection of ProtectionDomains.
464     //  *
465     //  * <p>
466     //  *
467     //  * @param subject the {@code Subject} that the specified
468     //  *                  {@code action} will run as.  This parameter
469     //  *                  may be {@code null}. <p>
470     //  *
471     //  * @param <T> the type of the value returned by the
472     //  *                  PrivilegedExceptionAction's {@code run} method.
473     //  *
474     //  * @param action the code to be run as the specified
475     //  *                  {@code Subject}. <p>
476     //  *
477     //  * @param acc the {@code AccessControlContext} to be tied to the
478     //  *                  specified <i>subject</i> and <i>action</i>. <p>
479     //  *
480     //  * @return the value returned by the
481     //  *                  PrivilegedExceptionAction's {@code run} method.
482     //  *
483     //  * @exception PrivilegedActionException if the
484     //  *                  {@code PrivilegedExceptionAction.run}
485     //  *                  method throws a checked exception. <p>
486     //  *
487     //  * @exception NullPointerException if the specified
488     //  *                  {@code PrivilegedExceptionAction} is
489     //  *                  {@code null}. <p>
490     //  *
491     //  * @exception SecurityException if the caller does not have permission
492     //  *                  to invoke this method.
493     //  */
494     // // static <T> T doAsPrivileged(Subject subject,
495     // //                     java.security.PrivilegedExceptionAction<T> action,
496     // //                     java.security.AccessControlContext acc)
497     // //                     throws java.security.PrivilegedActionException {
498 
499     // //     java.lang.SecurityManager sm = System.getSecurityManager();
500     // //     if (sm !is null) {
501     // //         sm.checkPermission(AuthPermissionHolder.DO_AS_PRIVILEGED_PERMISSION);
502     // //     }
503 
504     // //     if (action is null)
505     // //         throw new NullPointerException
506     // //             (ResourcesMgr.getString("invalid.null.action.provided"));
507 
508     // //     // set up the new Subject-based AccessControlContext for doPrivileged
509     // //     AccessControlContext callerAcc =
510     // //             (acc is null ?
511     // //             new AccessControlContext(NULL_PD_ARRAY) :
512     // //             acc);
513 
514     // //     // call doPrivileged and push this new context on the stack
515     // //     return java.security.AccessController.doPrivileged
516     // //                                     (action,
517     // //                                     createContext(subject, callerAcc));
518     // // }
519 
520     // // private static AccessControlContext createContext(Subject subject,
521     // //                                     AccessControlContext acc) {
522 
523 
524     // //     return java.security.AccessController.doPrivileged
525     // //         (new java.security.PrivilegedAction<AccessControlContext>() {
526     // //         AccessControlContext run() {
527     // //             if (subject is null)
528     // //                 return new AccessControlContext(acc, null);
529     // //             else
530     // //                 return new AccessControlContext
531     // //                                     (acc,
532     // //                                     new SubjectDomainCombiner(subject));
533     // //         }
534     // //     });
535     // // }
536 
537     // /**
538     //  * Return the {@code Set} of Principals associated with this
539     //  * {@code Subject}.  Each {@code Principal} represents
540     //  * an identity for this {@code Subject}.
541     //  *
542     //  * <p> The returned {@code Set} is backed by this Subject's
543     //  * internal {@code Principal} {@code Set}.  Any modification
544     //  * to the returned {@code Set} affects the internal
545     //  * {@code Principal} {@code Set} as well.
546     //  *
547     //  * <p>
548     //  *
549     //  * @return  The {@code Set} of Principals associated with this
550     //  *          {@code Subject}.
551     //  */
552     // Set!Principal getPrincipals() {
553 
554     //     // always return an empty Set instead of null
555     //     // so LoginModules can add to the Set if necessary
556     //     return principals;
557     // }
558 
559     // /**
560     //  * Return a {@code Set} of Principals associated with this
561     //  * {@code Subject} that are instances or subclasses of the specified
562     //  * {@code Class}.
563     //  *
564     //  * <p> The returned {@code Set} is not backed by this Subject's
565     //  * internal {@code Principal} {@code Set}.  A new
566     //  * {@code Set} is created and returned for each method invocation.
567     //  * Modifications to the returned {@code Set}
568     //  * will not affect the internal {@code Principal} {@code Set}.
569     //  *
570     //  * <p>
571     //  *
572     //  * @param <T> the type of the class modeled by {@code c}
573     //  *
574     //  * @param c the returned {@code Set} of Principals will all be
575     //  *          instances of this class.
576     //  *
577     //  * @return a {@code Set} of Principals that are instances of the
578     //  *          specified {@code Class}.
579     //  *
580     //  * @exception NullPointerException if the specified {@code Class}
581     //  *                  is {@code null}.
582     //  */
583     // <T : Principal> Set<T> getPrincipals(Class<T> c) {
584 
585     //     if (c is null)
586     //         throw new NullPointerException
587     //             (ResourcesMgr.getString("invalid.null.Class.provided"));
588 
589     //     // always return an empty Set instead of null
590     //     // so LoginModules can add to the Set if necessary
591     //     return new ClassSet<T>(PRINCIPAL_SET, c);
592     // }
593 
594     // /**
595     //  * Return the {@code Set} of credentials held by this
596     //  * {@code Subject}.
597     //  *
598     //  * <p> The returned {@code Set} is backed by this Subject's
599     //  * internal Credential {@code Set}.  Any modification
600     //  * to the returned {@code Set} affects the internal public
601     //  * Credential {@code Set} as well.
602     //  *
603     //  * <p>
604     //  *
605     //  * @return  A {@code Set} of credentials held by this
606     //  *          {@code Subject}.
607     //  */
608     // Set!Object getPublicCredentials() {
609 
610     //     // always return an empty Set instead of null
611     //     // so LoginModules can add to the Set if necessary
612     //     return pubCredentials;
613     // }
614 
615     // /**
616     //  * Return the {@code Set} of private credentials held by this
617     //  * {@code Subject}.
618     //  *
619     //  * <p> The returned {@code Set} is backed by this Subject's
620     //  * internal private Credential {@code Set}.  Any modification
621     //  * to the returned {@code Set} affects the internal private
622     //  * Credential {@code Set} as well.
623     //  *
624     //  * <p> A caller requires permissions to access the Credentials
625     //  * in the returned {@code Set}, or to modify the
626     //  * {@code Set} itself.  A {@code SecurityException}
627     //  * is thrown if the caller does not have the proper permissions.
628     //  *
629     //  * <p> While iterating through the {@code Set},
630     //  * a {@code SecurityException} is thrown
631     //  * if the caller does not have permission to access a
632     //  * particular Credential.  The {@code Iterator}
633     //  * is nevertheless advanced to next element in the {@code Set}.
634     //  *
635     //  * <p>
636     //  *
637     //  * @return  A {@code Set} of private credentials held by this
638     //  *          {@code Subject}.
639     //  */
640     // Set!Object getPrivateCredentials() {
641 
642     //     // XXX
643     //     // we do not need a security check for
644     //     // AuthPermission(getPrivateCredentials)
645     //     // because we already restrict access to private credentials
646     //     // via the PrivateCredentialPermission.  all the extra AuthPermission
647     //     // would do is protect the set operations themselves
648     //     // (like size()), which don't seem security-sensitive.
649 
650     //     // always return an empty Set instead of null
651     //     // so LoginModules can add to the Set if necessary
652     //     return privCredentials;
653     // }
654 
655     // /**
656     //  * Return a {@code Set} of credentials associated with this
657     //  * {@code Subject} that are instances or subclasses of the specified
658     //  * {@code Class}.
659     //  *
660     //  * <p> The returned {@code Set} is not backed by this Subject's
661     //  * internal Credential {@code Set}.  A new
662     //  * {@code Set} is created and returned for each method invocation.
663     //  * Modifications to the returned {@code Set}
664     //  * will not affect the internal Credential {@code Set}.
665     //  *
666     //  * <p>
667     //  *
668     //  * @param <T> the type of the class modeled by {@code c}
669     //  *
670     //  * @param c the returned {@code Set} of credentials will all be
671     //  *          instances of this class.
672     //  *
673     //  * @return a {@code Set} of credentials that are instances
674     //  *          of the  specified {@code Class}.
675     //  *
676     //  * @exception NullPointerException if the specified {@code Class}
677     //  *          is {@code null}.
678     //  */
679     // <T> Set<T> getPublicCredentials(Class<T> c) {
680 
681     //     if (c is null)
682     //         throw new NullPointerException
683     //             (ResourcesMgr.getString("invalid.null.Class.provided"));
684 
685     //     // always return an empty Set instead of null
686     //     // so LoginModules can add to the Set if necessary
687     //     return new ClassSet<T>(PUB_CREDENTIAL_SET, c);
688     // }
689 
690     // /**
691     //  * Return a {@code Set} of private credentials associated with this
692     //  * {@code Subject} that are instances or subclasses of the specified
693     //  * {@code Class}.
694     //  *
695     //  * <p> The caller must have permission to access all of the
696     //  * requested Credentials, or a {@code SecurityException}
697     //  * will be thrown.
698     //  *
699     //  * <p> The returned {@code Set} is not backed by this Subject's
700     //  * internal private Credential {@code Set}.  A new
701     //  * {@code Set} is created and returned for each method invocation.
702     //  * Modifications to the returned {@code Set}
703     //  * will not affect the internal private Credential {@code Set}.
704     //  *
705     //  * <p>
706     //  *
707     //  * @param <T> the type of the class modeled by {@code c}
708     //  *
709     //  * @param c the returned {@code Set} of private credentials will all be
710     //  *          instances of this class.
711     //  *
712     //  * @return a {@code Set} of private credentials that are instances
713     //  *          of the  specified {@code Class}.
714     //  *
715     //  * @exception NullPointerException if the specified {@code Class}
716     //  *          is {@code null}.
717     //  */
718     // <T> Set<T> getPrivateCredentials(Class<T> c) {
719 
720     //     // XXX
721     //     // we do not need a security check for
722     //     // AuthPermission(getPrivateCredentials)
723     //     // because we already restrict access to private credentials
724     //     // via the PrivateCredentialPermission.  all the extra AuthPermission
725     //     // would do is protect the set operations themselves
726     //     // (like size()), which don't seem security-sensitive.
727 
728     //     if (c is null)
729     //         throw new NullPointerException
730     //             (ResourcesMgr.getString("invalid.null.Class.provided"));
731 
732     //     // always return an empty Set instead of null
733     //     // so LoginModules can add to the Set if necessary
734     //     return new ClassSet<T>(PRIV_CREDENTIAL_SET, c);
735     // }
736 
737     // /**
738     //  * Compares the specified Object with this {@code Subject}
739     //  * for equality.  Returns true if the given object is also a Subject
740     //  * and the two {@code Subject} instances are equivalent.
741     //  * More formally, two {@code Subject} instances are
742     //  * equal if their {@code Principal} and {@code Credential}
743     //  * Sets are equal.
744     //  *
745     //  * <p>
746     //  *
747     //  * @param o Object to be compared for equality with this
748     //  *          {@code Subject}.
749     //  *
750     //  * @return true if the specified Object is equal to this
751     //  *          {@code Subject}.
752     //  *
753     //  * @exception SecurityException if the caller does not have permission
754     //  *          to access the private credentials for this {@code Subject},
755     //  *          or if the caller does not have permission to access the
756     //  *          private credentials for the provided {@code Subject}.
757     //  */
758     // bool equals(Object o) {
759 
760     //     if (o is null)
761     //         return false;
762 
763     //     if (this == o)
764     //         return true;
765 
766     //     if (o instanceof Subject) {
767 
768     //         Subject that = (Subject)o;
769 
770     //         // check the principal and credential sets
771     //         Set!Principal thatPrincipals;
772     //         synchronized(that.principals) {
773     //             // avoid deadlock from dual locks
774     //             thatPrincipals = new HashSet!Principal(that.principals);
775     //         }
776     //         if (!principals.equals(thatPrincipals)) {
777     //             return false;
778     //         }
779 
780     //         Set!Object thatPubCredentials;
781     //         synchronized(that.pubCredentials) {
782     //             // avoid deadlock from dual locks
783     //             thatPubCredentials = new HashSet!Object(that.pubCredentials);
784     //         }
785     //         if (!pubCredentials.equals(thatPubCredentials)) {
786     //             return false;
787     //         }
788 
789     //         Set!Object thatPrivCredentials;
790     //         synchronized(that.privCredentials) {
791     //             // avoid deadlock from dual locks
792     //             thatPrivCredentials = new HashSet!Object(that.privCredentials);
793     //         }
794     //         if (!privCredentials.equals(thatPrivCredentials)) {
795     //             return false;
796     //         }
797     //         return true;
798     //     }
799     //     return false;
800     // }
801 
802     // /**
803     //  * Return the string representation of this {@code Subject}.
804     //  *
805     //  * <p>
806     //  *
807     //  * @return the string representation of this {@code Subject}.
808     //  */
809     // string toString() {
810     //     return toString(true);
811     // }
812 
813     // /**
814     //  * package private convenience method to print out the Subject
815     //  * without firing off a security check when trying to access
816     //  * the Private Credentials
817     //  */
818     // string toString(bool includePrivateCredentials) {
819 
820     //     string s = ResourcesMgr.getString("Subject.");
821     //     string suffix = "";
822 
823     //     synchronized(principals) {
824     //         Iterator!Principal pI = principals.iterator();
825     //         while (pI.hasNext()) {
826     //             Principal p = pI.next();
827     //             suffix = suffix + ResourcesMgr.getString(".Principal.") +
828     //                     p.toString() + ResourcesMgr.getString("NEWLINE");
829     //         }
830     //     }
831 
832     //     synchronized(pubCredentials) {
833     //         Iterator!Object pI = pubCredentials.iterator();
834     //         while (pI.hasNext()) {
835     //             Object o = pI.next();
836     //             suffix = suffix +
837     //                     ResourcesMgr.getString(".Public.Credential.") +
838     //                     o.toString() + ResourcesMgr.getString("NEWLINE");
839     //         }
840     //     }
841 
842     //     if (includePrivateCredentials) {
843     //         synchronized(privCredentials) {
844     //             Iterator!Object pI = privCredentials.iterator();
845     //             while (pI.hasNext()) {
846     //                 try {
847     //                     Object o = pI.next();
848     //                     suffix += ResourcesMgr.getString
849     //                                     (".Private.Credential.") +
850     //                                     o.toString() +
851     //                                     ResourcesMgr.getString("NEWLINE");
852     //                 } catch (SecurityException se) {
853     //                     suffix += ResourcesMgr.getString
854     //                             (".Private.Credential.inaccessible.");
855     //                     break;
856     //                 }
857     //             }
858     //         }
859     //     }
860     //     return s + suffix;
861     // }
862 
863     // /**
864     //  * Returns a hashcode for this {@code Subject}.
865     //  *
866     //  * <p>
867     //  *
868     //  * @return a hashcode for this {@code Subject}.
869     //  *
870     //  * @exception SecurityException if the caller does not have permission
871     //  *          to access this Subject's private credentials.
872     //  */
873     // int toHash() {
874 
875     //     /**
876     //      * The hashcode is derived exclusive or-ing the
877     //      * hashcodes of this Subject's Principals and credentials.
878     //      *
879     //      * If a particular credential was destroyed
880     //      * ({@code credential.hashCode()} throws an
881     //      * {@code IllegalStateException}),
882     //      * the hashcode for that credential is derived via:
883     //      * {@code credential.getClass().toString().hashCode()}.
884     //      */
885 
886     //     int hashCode = 0;
887 
888     //     synchronized(principals) {
889     //         Iterator!Principal pIterator = principals.iterator();
890     //         while (pIterator.hasNext()) {
891     //             Principal p = pIterator.next();
892     //             hashCode ^= p.hashCode();
893     //         }
894     //     }
895 
896     //     synchronized(pubCredentials) {
897     //         Iterator!Object pubCIterator = pubCredentials.iterator();
898     //         while (pubCIterator.hasNext()) {
899     //             hashCode ^= getCredHashCode(pubCIterator.next());
900     //         }
901     //     }
902     //     return hashCode;
903     // }
904 
905     // /**
906     //  * get a credential's hashcode
907     //  */
908     // private int getCredHashCode(Object o) {
909     //     try {
910     //         return cast(int)o.toHash();
911     //     } catch (IllegalStateException ise) {
912     //         return cast(int) hashOf(typeid(o).toString());
913     //     }
914     // }
915 
916     // /**
917     //  * Writes this object out to a stream (i.e., serializes it).
918     //  */
919     // // private void writeObject(java.io.ObjectOutputStream oos)
920     // //             throws java.io.IOException {
921     // //     synchronized(principals) {
922     // //         oos.defaultWriteObject();
923     // //     }
924     // // }
925 
926     // /**
927     //  * Reads this object from a stream (i.e., deserializes it)
928     //  */
929     // @SuppressWarnings("unchecked")
930     // private void readObject(java.io.ObjectInputStream s)
931     //             throws java.io.IOException, ClassNotFoundException {
932 
933     //     ObjectInputStream.GetField gf = s.readFields();
934 
935     //     readOnly = gf.get("readOnly", false);
936 
937     //     Set!Principal inputPrincs = (Set!Principal)gf.get("principals", null);
938 
939     //     // Rewrap the principals into a SecureSet
940     //     if (inputPrincs is null) {
941     //         throw new NullPointerException
942     //             (ResourcesMgr.getString("invalid.null.input.s."));
943     //     }
944     //     try {
945     //         principals = Collections.synchronizedSet(new SecureSet!Principal
946     //                             (this, PRINCIPAL_SET, inputPrincs));
947     //     } catch (NullPointerException npe) {
948     //         // Sometimes people deserialize the principals set only.
949     //         // Subject is not accessible, so just don't fail.
950     //         principals = Collections.synchronizedSet
951     //                     (new SecureSet!Principal(this, PRINCIPAL_SET));
952     //     }
953 
954     //     // The Credential {@code Set} is not serialized, but we do not
955     //     // want the default deserialization routine to set it to null.
956     //     this.pubCredentials = Collections.synchronizedSet
957     //                     (new SecureSet!Object(this, PUB_CREDENTIAL_SET));
958     //     this.privCredentials = Collections.synchronizedSet
959     //                     (new SecureSet!Object(this, PRIV_CREDENTIAL_SET));
960     // }
961 
962     // /**
963     //  * Prevent modifications unless caller has permission.
964     //  *
965     //  * @serial include
966     //  */
967     // private static class SecureSet!(E) : AbstractSet!(E) {
968 
969     //     private enum long serialVersionUID = 7911754171111800359L;
970 
971     //     /**
972     //      * @serialField this$0 Subject The outer Subject instance.
973     //      * @serialField elements LinkedList The elements in this set.
974     //      */
975     //     // private static ObjectStreamField[] serialPersistentFields = {
976     //     //     new ObjectStreamField("this$0", Subject.class),
977     //     //     new ObjectStreamField("elements", LinkedList.class),
978     //     //     new ObjectStreamField("which", int.class)
979     //     // };
980 
981     //     Subject subject;
982     //     LinkedList!(E) elements;
983 
984     //     /**
985     //      * @serial An integer identifying the type of objects contained
986     //      *      in this set.  If {@code which == 1},
987     //      *      this is a Principal set and all the elements are
988     //      *      of type {@code java.security.Principal}.
989     //      *      If {@code which == 2}, this is a credential
990     //      *      set and all the elements are of type {@code Object}.
991     //      *      If {@code which == 3}, this is a private credential
992     //      *      set and all the elements are of type {@code Object}.
993     //      */
994     //     private int which;
995 
996     //     this(Subject subject, int which) {
997     //         this.subject = subject;
998     //         this.which = which;
999     //         this.elements = new LinkedList!(E)();
1000     //     }
1001 
1002     //     this(Subject subject, int which, Set!E set) {
1003     //         this.subject = subject;
1004     //         this.which = which;
1005     //         this.elements = new LinkedList!(E)(set);
1006     //     }
1007 
1008     //     int size() {
1009     //         return elements.size();
1010     //     }
1011 
1012     //     Iterator!(E) iterator() {
1013     //         LinkedList!(E) list = elements;
1014     //         return new class Iterator!(E) {
1015     //             ListIterator!(E) i = list.listIterator(0);
1016 
1017     //             bool hasNext() {return i.hasNext();}
1018 
1019     //             E next() {
1020     //                 if (which != Subject.PRIV_CREDENTIAL_SET) {
1021     //                     return i.next();
1022     //                 }
1023 
1024     //                 SecurityManager sm = System.getSecurityManager();
1025     //                 if (sm !is null) {
1026     //                     try {
1027     //                         sm.checkPermission(new PrivateCredentialPermission
1028     //                             (list.get(i.nextIndex()).getClass().getName(),
1029     //                             subject.getPrincipals()));
1030     //                     } catch (SecurityException se) {
1031     //                         i.next();
1032     //                         throw (se);
1033     //                     }
1034     //                 }
1035     //                 return i.next();
1036     //             }
1037 
1038     //             void remove() {
1039 
1040     //                 if (subject.isReadOnly()) {
1041     //                     throw new IllegalStateException(ResourcesMgr.getString
1042     //                             ("Subject.is.read.only"));
1043     //                 }
1044 
1045     //                 java.lang.SecurityManager sm = System.getSecurityManager();
1046     //                 if (sm !is null) {
1047     //                     switch (which) {
1048     //                     case Subject.PRINCIPAL_SET:
1049     //                         sm.checkPermission(AuthPermissionHolder.MODIFY_PRINCIPALS_PERMISSION);
1050     //                         break;
1051     //                     case Subject.PUB_CREDENTIAL_SET:
1052     //                         sm.checkPermission(AuthPermissionHolder.MODIFY_PUBLIC_CREDENTIALS_PERMISSION);
1053     //                         break;
1054     //                     default:
1055     //                         sm.checkPermission(AuthPermissionHolder.MODIFY_PRIVATE_CREDENTIALS_PERMISSION);
1056     //                         break;
1057     //                     }
1058     //                 }
1059     //                 i.remove();
1060     //             }
1061     //         };
1062     //     }
1063 
1064     //     bool add(E o) {
1065 
1066     //         if (subject.isReadOnly()) {
1067     //             throw new IllegalStateException
1068     //                     (ResourcesMgr.getString("Subject.is.read.only"));
1069     //         }
1070 
1071     //         java.lang.SecurityManager sm = System.getSecurityManager();
1072     //         if (sm !is null) {
1073     //             switch (which) {
1074     //             case Subject.PRINCIPAL_SET:
1075     //                 sm.checkPermission(AuthPermissionHolder.MODIFY_PRINCIPALS_PERMISSION);
1076     //                 break;
1077     //             case Subject.PUB_CREDENTIAL_SET:
1078     //                 sm.checkPermission(AuthPermissionHolder.MODIFY_PUBLIC_CREDENTIALS_PERMISSION);
1079     //                 break;
1080     //             default:
1081     //                 sm.checkPermission(AuthPermissionHolder.MODIFY_PRIVATE_CREDENTIALS_PERMISSION);
1082     //                 break;
1083     //             }
1084     //         }
1085 
1086     //         switch (which) {
1087     //         case Subject.PRINCIPAL_SET:
1088     //             if (!(o instanceof Principal)) {
1089     //                 throw new SecurityException(ResourcesMgr.getString
1090     //                     ("attempting.to.add.an.object.which.is.not.an.instance.of.java.security.Principal.to.a.Subject.s.Principal.Set"));
1091     //             }
1092     //             break;
1093     //         default:
1094     //             // ok to add Objects of any kind to credential sets
1095     //             break;
1096     //         }
1097 
1098     //         // check for duplicates
1099     //         if (!elements.contains(o))
1100     //             return elements.add(o);
1101     //         else
1102     //             return false;
1103     //     }
1104 
1105     //     bool remove(Object o) {
1106 
1107     //         Iterator!(E) e = iterator();
1108     //         while (e.hasNext()) {
1109     //             E next;
1110     //             if (which != Subject.PRIV_CREDENTIAL_SET) {
1111     //                 next = e.next();
1112     //             } else {
1113     //                 next = java.security.AccessController.doPrivileged
1114     //                     (new java.security.PrivilegedAction!(E)() {
1115     //                     E run() {
1116     //                         return e.next();
1117     //                     }
1118     //                 });
1119     //             }
1120 
1121     //             if (next is null) {
1122     //                 if (o is null) {
1123     //                     e.remove();
1124     //                     return true;
1125     //                 }
1126     //             } else if (next.equals(o)) {
1127     //                 e.remove();
1128     //                 return true;
1129     //             }
1130     //         }
1131     //         return false;
1132     //     }
1133 
1134     //     bool contains(Object o) {
1135     //         Iterator!(E) e = iterator();
1136     //         while (e.hasNext()) {
1137     //             E next;
1138     //             if (which != Subject.PRIV_CREDENTIAL_SET) {
1139     //                 next = e.next();
1140     //             } else {
1141 
1142     //                 // For private credentials:
1143     //                 // If the caller does not have read permission for
1144     //                 // for o.getClass(), we throw a SecurityException.
1145     //                 // Otherwise we check the private cred set to see whether
1146     //                 // it contains the Object
1147 
1148     //                 SecurityManager sm = System.getSecurityManager();
1149     //                 if (sm !is null) {
1150     //                     sm.checkPermission(new PrivateCredentialPermission
1151     //                                             (o.getClass().getName(),
1152     //                                             subject.getPrincipals()));
1153     //                 }
1154     //                 next = java.security.AccessController.doPrivileged
1155     //                     (new java.security.PrivilegedAction!(E)() {
1156     //                     E run() {
1157     //                         return e.next();
1158     //                     }
1159     //                 });
1160     //             }
1161 
1162     //             if (next is null) {
1163     //                 if (o is null) {
1164     //                     return true;
1165     //                 }
1166     //             } else if (next.equals(o)) {
1167     //                 return true;
1168     //             }
1169     //         }
1170     //         return false;
1171     //     }
1172 
1173     //     bool removeAll(Collection<?> c) {
1174     //         Objects.requireNonNull(c);
1175     //         bool modified = false;
1176     //         Iterator!(E) e = iterator();
1177     //         while (e.hasNext()) {
1178     //             E next;
1179     //             if (which != Subject.PRIV_CREDENTIAL_SET) {
1180     //                 next = e.next();
1181     //             } else {
1182     //                 next = java.security.AccessController.doPrivileged
1183     //                     (new java.security.PrivilegedAction!(E)() {
1184     //                     E run() {
1185     //                         return e.next();
1186     //                     }
1187     //                 });
1188     //             }
1189 
1190     //             Iterator<?> ce = c.iterator();
1191     //             while (ce.hasNext()) {
1192     //                 Object o = ce.next();
1193     //                 if (next is null) {
1194     //                     if (o is null) {
1195     //                         e.remove();
1196     //                         modified = true;
1197     //                         break;
1198     //                     }
1199     //                 } else if (next.equals(o)) {
1200     //                     e.remove();
1201     //                     modified = true;
1202     //                     break;
1203     //                 }
1204     //             }
1205     //         }
1206     //         return modified;
1207     //     }
1208 
1209     //     bool retainAll(Collection<?> c) {
1210     //         Objects.requireNonNull(c);
1211     //         bool modified = false;
1212     //         bool retain = false;
1213     //         Iterator!(E) e = iterator();
1214     //         while (e.hasNext()) {
1215     //             retain = false;
1216     //             E next;
1217     //             if (which != Subject.PRIV_CREDENTIAL_SET) {
1218     //                 next = e.next();
1219     //             } else {
1220     //                 next = java.security.AccessController.doPrivileged
1221     //                     (new java.security.PrivilegedAction!(E)() {
1222     //                     E run() {
1223     //                         return e.next();
1224     //                     }
1225     //                 });
1226     //             }
1227 
1228     //             Iterator<?> ce = c.iterator();
1229     //             while (ce.hasNext()) {
1230     //                 Object o = ce.next();
1231     //                 if (next is null) {
1232     //                     if (o is null) {
1233     //                         retain = true;
1234     //                         break;
1235     //                     }
1236     //                 } else if (next.equals(o)) {
1237     //                     retain = true;
1238     //                     break;
1239     //                 }
1240     //             }
1241 
1242     //             if (!retain) {
1243     //                 e.remove();
1244     //                 retain = false;
1245     //                 modified = true;
1246     //             }
1247     //         }
1248     //         return modified;
1249     //     }
1250 
1251     //     void clear() {
1252     //         // Iterator!(E) e = iterator();
1253     //         // while (e.hasNext()) {
1254     //         //     E next;
1255     //         //     if (which != Subject.PRIV_CREDENTIAL_SET) {
1256     //         //         next = e.next();
1257     //         //     } else {
1258     //         //         next = java.security.AccessController.doPrivileged
1259     //         //             (new java.security.PrivilegedAction!(E)() {
1260     //         //             E run() {
1261     //         //                 return e.next();
1262     //         //             }
1263     //         //         });
1264     //         //     }
1265     //         //     e.remove();
1266     //         // }
1267     //     }
1268 
1269     //     /**
1270     //      * Writes this object out to a stream (i.e., serializes it).
1271     //      *
1272     //      * <p>
1273     //      *
1274     //      * @serialData If this is a private credential set,
1275     //      *      a security check is performed to ensure that
1276     //      *      the caller has permission to access each credential
1277     //      *      in the set.  If the security check passes,
1278     //      *      the set is serialized.
1279     //      */
1280     //     // private void writeObject(java.io.ObjectOutputStream oos)
1281     //     //         throws java.io.IOException {
1282 
1283     //     //     if (which == Subject.PRIV_CREDENTIAL_SET) {
1284     //     //         // check permissions before serializing
1285     //     //         Iterator!(E) i = iterator();
1286     //     //         while (i.hasNext()) {
1287     //     //             i.next();
1288     //     //         }
1289     //     //     }
1290     //     //     ObjectOutputStream.PutField fields = oos.putFields();
1291     //     //     fields.put("this$0", subject);
1292     //     //     fields.put("elements", elements);
1293     //     //     fields.put("which", which);
1294     //     //     oos.writeFields();
1295     //     // }
1296 
1297     //     // private void readObject(ObjectInputStream ois)
1298     //     // {
1299     //     //     ObjectInputStream.GetField fields = ois.readFields();
1300     //     //     subject = (Subject) fields.get("this$0", null);
1301     //     //     which = fields.get("which", 0);
1302 
1303     //     //     LinkedList!(E) tmp = (LinkedList!(E)) fields.get("elements", null);
1304     //     //     if (tmp.getClass() != LinkedList.class) {
1305     //     //         elements = new LinkedList!(E)(tmp);
1306     //     //     } else {
1307     //     //         elements = tmp;
1308     //     //     }
1309     //     // }
1310     // }
1311 
1312     // /**
1313     //  * This class implements a {@code Set} which returns only
1314     //  * members that are an instance of a specified Class.
1315     //  */
1316     // private class ClassSet<T> : AbstractSet<T> {
1317 
1318     //     private int which;
1319     //     private Class<T> c;
1320     //     private Set<T> set;
1321 
1322     //     ClassSet(int which, Class<T> c) {
1323     //         this.which = which;
1324     //         this.c = c;
1325     //         set = new HashSet<T>();
1326 
1327     //         switch (which) {
1328     //         case Subject.PRINCIPAL_SET:
1329     //             synchronized(principals) { populateSet(); }
1330     //             break;
1331     //         case Subject.PUB_CREDENTIAL_SET:
1332     //             synchronized(pubCredentials) { populateSet(); }
1333     //             break;
1334     //         default:
1335     //             synchronized(privCredentials) { populateSet(); }
1336     //             break;
1337     //         }
1338     //     }
1339 
1340     //     @SuppressWarnings("unchecked")     /*To suppress warning from line 1374*/
1341     //     private void populateSet() {
1342     //         Iterator<?> iterator;
1343     //         switch(which) {
1344     //         case Subject.PRINCIPAL_SET:
1345     //             iterator = Subject.this.principals.iterator();
1346     //             break;
1347     //         case Subject.PUB_CREDENTIAL_SET:
1348     //             iterator = Subject.this.pubCredentials.iterator();
1349     //             break;
1350     //         default:
1351     //             iterator = Subject.this.privCredentials.iterator();
1352     //             break;
1353     //         }
1354 
1355     //         // Check whether the caller has permisson to get
1356     //         // credentials of Class c
1357 
1358     //         while (iterator.hasNext()) {
1359     //             Object next;
1360     //             if (which == Subject.PRIV_CREDENTIAL_SET) {
1361     //                 next = java.security.AccessController.doPrivileged
1362     //                     (new java.security.PrivilegedAction!Object() {
1363     //                     Object run() {
1364     //                         return iterator.next();
1365     //                     }
1366     //                 });
1367     //             } else {
1368     //                 next = iterator.next();
1369     //             }
1370     //             if (c.isAssignableFrom(next.getClass())) {
1371     //                 if (which != Subject.PRIV_CREDENTIAL_SET) {
1372     //                     set.add((T)next);
1373     //                 } else {
1374     //                     // Check permission for private creds
1375     //                     SecurityManager sm = System.getSecurityManager();
1376     //                     if (sm !is null) {
1377     //                         sm.checkPermission(new PrivateCredentialPermission
1378     //                                             (next.getClass().getName(),
1379     //                                             Subject.this.getPrincipals()));
1380     //                     }
1381     //                     set.add((T)next);
1382     //                 }
1383     //             }
1384     //         }
1385     //     }
1386 
1387     //     int size() {
1388     //         return set.size();
1389     //     }
1390 
1391     //     Iterator<T> iterator() {
1392     //         return set.iterator();
1393     //     }
1394 
1395     //     bool add(T o) {
1396 
1397     //         if (!o.getClass().isAssignableFrom(c)) {
1398     //             MessageFormat form = new MessageFormat(ResourcesMgr.getString
1399     //                     ("attempting.to.add.an.object.which.is.not.an.instance.of.class"));
1400     //             Object[] source = {c.toString()};
1401     //             throw new SecurityException(form.format(source));
1402     //         }
1403 
1404     //         return set.add(o);
1405     //     }
1406     // }
1407 
1408     // static class AuthPermissionHolder {
1409     //     static AuthPermission DO_AS_PERMISSION =
1410     //         new AuthPermission("doAs");
1411 
1412     //     static AuthPermission DO_AS_PRIVILEGED_PERMISSION =
1413     //         new AuthPermission("doAsPrivileged");
1414 
1415     //     static AuthPermission SET_READ_ONLY_PERMISSION =
1416     //         new AuthPermission("setReadOnly");
1417 
1418     //     static AuthPermission GET_SUBJECT_PERMISSION =
1419     //         new AuthPermission("getSubject");
1420 
1421     //     static AuthPermission MODIFY_PRINCIPALS_PERMISSION =
1422     //         new AuthPermission("modifyPrincipals");
1423 
1424     //     static AuthPermission MODIFY_PUBLIC_CREDENTIALS_PERMISSION =
1425     //         new AuthPermission("modifyPublicCredentials");
1426 
1427     //     static AuthPermission MODIFY_PRIVATE_CREDENTIALS_PERMISSION =
1428     //         new AuthPermission("modifyPrivateCredentials");
1429     // }
1430 }