- java.lang.Object
- 
- java.security.AccessController
 
- 
 public final class AccessController extends Object AccessControllerクラスは、アクセス制御の操作と決定に使用されます。 具体的には、AccessControllerクラスを次の3つの目的で使用します。 - 現在有効なセキュリティ・ポリシーに基づいて、重要なシステム・リソースへのアクセスが許可されるか、拒否されるかを決定する。
- コードを「特権」が与えられたものとしてマークし、以降のアクセスの決定に影響を与える。
- アクセス制御が保存したコンテキストに関して用意される別のコンテキストから決定できるように、現在の呼出し側コンテキストの「スナップショット」を取得する。
 checkPermissionメソッドは、指定されたアクセス権によって示されるアクセス要求が許可されるか、拒否されるかを決定します。 呼出しの例を次に示します。 この例では、checkPermissionは、/tempディレクトリのtestFileというファイルへの読込み権を許可するかどうかを決定します。FilePermission perm = new FilePermission("/temp/testFile", "read"); AccessController.checkPermission(perm);要求されたアクセス権が許可される場合、 checkPermissionは何もしないで復帰します。 アクセスが拒否される場合には、AccessControlExceptionがスローされます。 AccessControlExceptionは、要求されたアクセス権が不正な型であったり、無効な値を含んでいたりした場合にもスローされる可能性があります。 可能な場合には、そうした情報が提供されます。 現在のスレッドが呼出し元1、呼出し元2、呼出し元mの順でm個の呼出し元をトラバースしたとします。 次に、呼出し元mはcheckPermissionメソッドを呼び出しました。 このとき、checkPermissionメソッドは次のアルゴリズムに基づいて、アクセスが許可されるか拒否されるかを決定します。for (int i = m; i > 0; i--) { if (caller i's domain does not have the permission) throw AccessControlException else if (caller i is marked as privileged) { if (a context was specified in the call to doPrivileged) context.checkPermission(permission) if (limited permissions were specified in the call to doPrivileged) { for (each limited permission) { if (the limited permission implies the requested permission) return; } } else return; } } // Next, check the context inherited when the thread was created. // Whenever a new thread is created, the AccessControlContext at // that time is stored and associated with the new thread, as the // "inherited" context. inheritedContext.checkPermission(permission);呼出し側は、特権コードとしてマークできます( doPrivilegedおよび次の説明を参照)。 アクセス制御を決定する場合、checkPermissionメソッドは、コンテキスト引数のないdoPrivilegedの呼出しによって特権コードとしてマークされた呼出し側に届いたときに、検査を中止します(コンテキスト引数については、次の説明を参照)。 その呼出し元のドメインが指定されたアクセス権を持っていて、少なくとも1つのアクセス権制限引数(あれば)に要求されたアクセス権が含まれている場合、checkPermissionはそれ以上のチェックを行わずに正常復帰し、要求されたアクセスが許可されていることを示します。 そのドメインが指定されたアクセス権を持たない場合は、通常は例外が発行されます。 呼出し元のドメインが指定されたアクセス権を持っているが、doPrivilegedの呼出し時に指定されたアクセス権制限引数にそれが含まれていない場合は、呼出し元が存在しなくなるか、別のdoPrivileged呼出しが要求されたアクセス権と一致して正常に復帰するまで、アクセス権のチェックが続行されます。次に、特権機能の通常の使い方を説明します。 「特権付き」ブロックからの戻り値が必要ない場合は、次のようにします。 somemethod() { ...normal code here... AccessController.doPrivileged(new PrivilegedAction<Void>() { public Void run() { // privileged code goes here, for example: System.loadLibrary("awt"); return null; // nothing to return } }); ...normal code here... }PrivilegedActionは、 runという名前の単一のメソッドを持つインタフェースです。 上記の例は、そのインタフェースの実装の作成方法を示しています。つまり、runメソッドの具象実装が提供されます。doPrivilegedへの呼出し時に、PrivilegedActionの実装のインスタンスが渡されます。doPrivilegedメソッドは、特権を有効にしたあとで、PrivilegedActionの実装からrunメソッドを呼び出し、runメソッドの戻り値をdoPrivilegedの戻り値として返します。上の例では戻り値は無視されています。次に、値を返す必要がある場合の例を示します。 somemethod() { ...normal code here... String user = AccessController.doPrivileged( new PrivilegedAction<String>() { public String run() { return System.getProperty("user.name"); } }); ...normal code here... }runメソッドで実行したアクションが「チェック」例外(メソッドのthrows節に表示されている例外)をスローする可能性がある場合には、PrivilegedActionインタフェースの代わりにPrivilegedExceptionActionインタフェースを使用する必要があります。somemethod() throws FileNotFoundException { ...normal code here... try { FileInputStream fis = AccessController.doPrivileged( new PrivilegedExceptionAction<FileInputStream>() { public FileInputStream run() throws FileNotFoundException { return new FileInputStream("someFile"); } }); } catch (PrivilegedActionException e) { // e.getException() should be an instance of FileNotFoundException, // as only "checked" exceptions will be "wrapped" in a // PrivilegedActionException. throw (FileNotFoundException) e.getException(); } ...normal code here... }特権構造の使用には細心の注意を払って、特権コード・セクションをできるだけ小さくしてください。 Permission引数を渡して「特権」のスコープをさらに制限できます(次を参照)。checkPermissionは、常に現在実行しているスレッドのコンテキスト内でセキュリティ・チェックを行います。 しかし実際には、指定されたコンテキスト内で行うセキュリティ・チェックを、別のコンテキスト内から(たとえば、ワーカー・スレッド内から)行わなければならない場合もあります。 この状況に対応するために、getContextメソッドとAccessControlContextクラスが提供されています。getContextメソッドは、現在の呼出しコンテキストをAccessControlContextオブジェクトに格納して返します。 呼出しの例を次に示します。AccessControlContext acc = AccessController.getContext() AccessControlContext自体が checkPermissionメソッドを持っており、このメソッドを使って、現在の実行スレッドのコンテキストではなくカプセル化しているコンテキストに基づいてアクセスの判断を行います。 したがって、別のコンテキスト内のコードは、以前に保存したAccessControlContextオブジェクトを呼び出すことができます。 呼出しの例を次に示します。acc.checkPermission(permission) また、コンテキストをどのアクセス権で検査するかが、事前には不明な場合があります。 これらのケースでは、コンテキストを取るdoPrivilegedメソッドを使用できます。 追加の Permissionパラメータを渡すことによって、特権コードのスコープを制限することもできます。somemethod() { AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { // Code goes here. Any permission checks within this // run method will require that the intersection of the // caller's protection domain and the snapshot's // context have the desired permission. If a requested // permission is not implied by the limiting FilePermission // argument then checking of the thread continues beyond the // caller of doPrivileged. } }, acc, new FilePermission("/temp/*", read)); ...normal code here... }AllPermissionのインスタンスのPermission制限引数を渡すことは、Permission制限引数なしで同等のdoPrivilegedを呼び出すことと同じです。 長さゼロのPermissionの配列を渡すと、コードの特権が無効になるため、そのdoPrivilegedメソッドの呼出し元を超えて常にチェックが続行されます。- 導入されたバージョン:
- 1.2
- 関連項目:
- AccessControlContext
 
- 
- 
メソッドのサマリーすべてのメソッド staticメソッド 具象メソッド 修飾子と型 メソッド 説明 static voidcheckPermission(Permission perm)現在のAccessControlContextとセキュリティ・ポリシーに基づいて、指定されたアクセス権によって示されるアクセス要求が許可されるか拒否されるかを決定します。static <T> TdoPrivileged(PrivilegedAction<T> action)有効になった特権を使って、指定されたPrivilegedActionを実行します。static <T> TdoPrivileged(PrivilegedAction<T> action, AccessControlContext context)指定されたAccessControlContextによって有効になり、かつ制限される特権を使って、指定されたPrivilegedActionを実行します。static <T> TdoPrivileged(PrivilegedAction<T> action, AccessControlContext context, Permission... perms)指定されたAccessControlContextによって許可および制限される特権と、指定されたPermission引数によって制限される特権範囲を使用して、指定されたPrivilegedActionを実行します。static <T> TdoPrivileged(PrivilegedExceptionAction<T> action)有効になった特権を使って、指定されたPrivilegedExceptionActionを実行します。static <T> TdoPrivileged(PrivilegedExceptionAction<T> action, AccessControlContext context)指定されたAccessControlContextによって有効になり、かつ制限される特権を使って、指定されたPrivilegedExceptionActionを実行します。static <T> TdoPrivileged(PrivilegedExceptionAction<T> action, AccessControlContext context, Permission... perms)指定されたAccessControlContextによって許可および制限される特権と、指定されたPermission引数によって制限される特権範囲を使用して、指定されたPrivilegedExceptionActionを実行します。static <T> TdoPrivilegedWithCombiner(PrivilegedAction<T> action)有効になった特権を使って、指定されたPrivilegedActionを実行します。static <T> TdoPrivilegedWithCombiner(PrivilegedAction<T> action, AccessControlContext context, Permission... perms)指定されたAccessControlContextによって許可および制限される特権と、指定されたPermission引数によって制限される特権範囲を使用して、指定されたPrivilegedActionを実行します。static <T> TdoPrivilegedWithCombiner(PrivilegedExceptionAction<T> action)有効になった特権を使って、指定されたPrivilegedExceptionActionを実行します。static <T> TdoPrivilegedWithCombiner(PrivilegedExceptionAction<T> action, AccessControlContext context, Permission... perms)指定されたAccessControlContextによって許可および制限される特権と、指定されたPermission引数によって制限される特権範囲を使用して、指定されたPrivilegedExceptionActionを実行します。static AccessControlContextgetContext()このメソッドは、現在のスレッドの継承されたAccessControlContextと制限された特権スコープを含む、現在の呼出し側コンテキストの「スナップショット」を取得し、それをAccessControlContextオブジェクトに配置します。
 
- 
- 
- 
メソッドの詳細- 
doPrivilegedpublic static <T> T doPrivileged(PrivilegedAction<T> action) 有効になった特権を使って、指定されたPrivilegedActionを実行します。 アクションは、呼出し側の保護領域で所有しているすべてのアクセス権を使って実行されます。アクションの runメソッドが(非チェック)例外をスローすると、例外はこのメソッドを使って送られます。アクションの実行中、現在のAccessControlContextに関連付けられているDomainCombinerは無視されます。 - 型パラメータ:
- T- PrivilegedActionの- runメソッドによって返される値の型。
- パラメータ:
- action- 実行されるアクション。
- 戻り値:
- アクションのrunメソッドによって返される値。
- 例外:
- NullPointerException- アクションが次の場合:- null
- 関連項目:
- doPrivileged(PrivilegedAction,AccessControlContext),- doPrivileged(PrivilegedExceptionAction),- doPrivilegedWithCombiner(PrivilegedAction),- DomainCombiner
 
 - 
doPrivilegedWithCombinerpublic static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action) 有効になった特権を使って、指定されたPrivilegedActionを実行します。 アクションは、呼出し側の保護領域で所有しているすべてのアクセス権を使って実行されます。アクションの runメソッドが(非チェック)例外をスローすると、例外はこのメソッドを使って送られます。このメソッドは、アクションの実行中、現在のAccessControlContextのDomainCombiner (nullの場合もある)を保存します。 - 型パラメータ:
- T- PrivilegedActionの- runメソッドによって返される値の型。
- パラメータ:
- action- 実行されるアクション。
- 戻り値:
- アクションのrunメソッドによって返される値。
- 例外:
- NullPointerException- アクションが次の場合:- null
- 導入されたバージョン:
- 1.6
- 関連項目:
- doPrivileged(PrivilegedAction),- DomainCombiner
 
 - 
doPrivilegedpublic static <T> T doPrivileged(PrivilegedAction<T> action, AccessControlContext context) 指定されたAccessControlContextによって有効になり、かつ制限される特権を使って、指定されたPrivilegedActionを実行します。 アクションは、呼出し側の保護領域で所有しているアクセス権と、指定されたAccessControlContextによって表される領域で所有しているアクセス権の共通部分を使って実行されます。アクションの runメソッドが(非チェック)例外をスローすると、例外はこのメソッドを使って送られます。セキュリティ・マネージャがインストールされ、指定された AccessControlContextがシステム・コードによって作成されず、呼出し元のProtectionDomainに「createAccessControlContext」SecurityPermissionが付与されていない場合、そのアクションはアクセス権なしで実行されます。- 型パラメータ:
- T- PrivilegedActionの- runメソッドによって返される値の型。
- パラメータ:
- action- 実行されるアクション。
- context- 指定されたアクションの実行前に呼出し側のドメインの特権に適用される制限を表す、アクセス制御コンテキスト。 コンテキストが- nullの場合、追加の制限は適用されない。
- 戻り値:
- アクションのrunメソッドによって返される値。
- 例外:
- NullPointerException- アクションが次の場合:- null
- 関連項目:
- doPrivileged(PrivilegedAction),- doPrivileged(PrivilegedExceptionAction,AccessControlContext)
 
 - 
doPrivilegedpublic static <T> T doPrivileged(PrivilegedAction<T> action, AccessControlContext context, Permission... perms) 指定されたAccessControlContextによって許可および制限される特権と、指定されたPermission引数によって制限される特権範囲を使用して、指定されたPrivilegedActionを実行します。 アクションは、呼出し側の保護領域で所有しているアクセス権と、指定されたAccessControlContextによって表される領域で所有しているアクセス権の共通部分を使って実行されます。アクションの runメソッドが(非チェック)例外をスローすると、例外はこのメソッドを使って送られます。セキュリティ・マネージャがインストールされ、指定された AccessControlContextがシステム・コードによって作成されず、呼出し元のProtectionDomainに「createAccessControlContext」SecurityPermissionが付与されていない場合、そのアクションはアクセス権なしで実行されます。- 型パラメータ:
- T- PrivilegedActionの- runメソッドによって返される値の型。
- パラメータ:
- action- 実行されるアクション。
- context- 指定されたアクションの実行前に呼出し側のドメインの特権に適用される制限を表す、アクセス制御コンテキスト。 コンテキストが- nullの場合、追加の制限は適用されない。
- perms- 呼出し元の特権のスコープを制限する- Permission引数。 引数の数は変動する。
- 戻り値:
- アクションのrunメソッドによって返される値。
- 例外:
- NullPointerException- action、permsまたはpermsのいずれかの要素が- nullである場合
- 導入されたバージョン:
- 1.8
- 関連項目:
- doPrivileged(PrivilegedAction),- doPrivileged(PrivilegedExceptionAction,AccessControlContext)
 
 - 
doPrivilegedWithCombinerpublic static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action, AccessControlContext context, Permission... perms) 指定されたAccessControlContextによって許可および制限される特権と、指定されたPermission引数によって制限される特権範囲を使用して、指定されたPrivilegedActionを実行します。 アクションは、呼出し側の保護領域で所有しているアクセス権と、指定されたAccessControlContextによって表される領域で所有しているアクセス権の共通部分を使って実行されます。アクションの runメソッドが(非チェック)例外をスローすると、例外はこのメソッドを使って送られます。このメソッドは、アクションの実行中、現在のAccessControlContextのDomainCombiner (nullの場合もある)を保存します。 セキュリティ・マネージャがインストールされ、指定された AccessControlContextがシステム・コードによって作成されず、呼出し元のProtectionDomainに「createAccessControlContext」SecurityPermissionが付与されていない場合、そのアクションはアクセス権なしで実行されます。- 型パラメータ:
- T- PrivilegedActionの- runメソッドによって返される値の型。
- パラメータ:
- action- 実行されるアクション。
- context- 指定されたアクションの実行前に呼出し側のドメインの特権に適用される制限を表す、アクセス制御コンテキスト。 コンテキストが- nullの場合、追加の制限は適用されない。
- perms- 呼出し元の特権のスコープを制限する- Permission引数。 引数の数は変動する。
- 戻り値:
- アクションのrunメソッドによって返される値。
- 例外:
- NullPointerException- action、permsまたはpermsのいずれかの要素が- nullである場合
- 導入されたバージョン:
- 1.8
- 関連項目:
- doPrivileged(PrivilegedAction),- doPrivileged(PrivilegedExceptionAction,AccessControlContext),- DomainCombiner
 
 - 
doPrivilegedpublic static <T> T doPrivileged(PrivilegedExceptionAction<T> action) throws PrivilegedActionException 有効になった特権を使って、指定されたPrivilegedExceptionActionを実行します。 アクションは、呼出し側の保護領域で所有しているすべてのアクセス権を使って実行されます。アクションの runメソッドがチェック例外をスローすると、例外はこのメソッドを使って送られます。アクションの実行中、現在のAccessControlContextに関連付けられているDomainCombinerは無視されます。 - 型パラメータ:
- T- PrivilegedExceptionActionの- runメソッドによって返される値の型。
- パラメータ:
- action- 実行されるアクション
- 戻り値:
- アクションのrunメソッドによって返される値
- 例外:
- PrivilegedActionException- 指定されたアクションの- runメソッドがチェック例外をスローした場合
- NullPointerException- アクションが次の場合:- null
- 関連項目:
- doPrivileged(PrivilegedAction),- doPrivileged(PrivilegedExceptionAction,AccessControlContext),- doPrivilegedWithCombiner(PrivilegedExceptionAction),- DomainCombiner
 
 - 
doPrivilegedWithCombinerpublic static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action) throws PrivilegedActionException 有効になった特権を使って、指定されたPrivilegedExceptionActionを実行します。 アクションは、呼出し側の保護領域で所有しているすべてのアクセス権を使って実行されます。アクションの runメソッドがチェック例外をスローすると、例外はこのメソッドを使って送られます。このメソッドは、アクションの実行中、現在のAccessControlContextのDomainCombiner (nullの場合もある)を保存します。 - 型パラメータ:
- T- PrivilegedExceptionActionの- runメソッドによって返される値の型。
- パラメータ:
- action- 実行されるアクション。
- 戻り値:
- アクションのrunメソッドによって返される値
- 例外:
- PrivilegedActionException- 指定されたアクションの- runメソッドがチェック例外をスローした場合
- NullPointerException- アクションが次の場合:- null
- 導入されたバージョン:
- 1.6
- 関連項目:
- doPrivileged(PrivilegedAction),- doPrivileged(PrivilegedExceptionAction,AccessControlContext),- DomainCombiner
 
 - 
doPrivilegedpublic static <T> T doPrivileged(PrivilegedExceptionAction<T> action, AccessControlContext context) throws PrivilegedActionException 指定されたAccessControlContextによって有効になり、かつ制限される特権を使って、指定されたPrivilegedExceptionActionを実行します。 アクションは、呼出し側の保護領域で所有しているアクセス権と、指定されたAccessControlContextによって表される領域で所有しているアクセス権の共通部分を使って実行されます。アクションの runメソッドがチェック例外をスローすると、例外はこのメソッドを使って送られます。セキュリティ・マネージャがインストールされ、指定された AccessControlContextがシステム・コードによって作成されず、呼出し元のProtectionDomainに「createAccessControlContext」SecurityPermissionが付与されていない場合、そのアクションはアクセス権なしで実行されます。- 型パラメータ:
- T- PrivilegedExceptionActionの- runメソッドによって返される値の型。
- パラメータ:
- action- 実行されるアクション
- context- 指定されたアクションの実行前に呼出し側のドメインの特権に適用される制限を表す、アクセス制御コンテキスト。 コンテキストが- nullの場合、追加の制限は適用されない。
- 戻り値:
- アクションのrunメソッドによって返される値
- 例外:
- PrivilegedActionException- 指定されたアクションの- runメソッドがチェック例外をスローした場合
- NullPointerException- アクションが次の場合:- null
- 関連項目:
- doPrivileged(PrivilegedAction),- doPrivileged(PrivilegedAction,AccessControlContext)
 
 - 
doPrivilegedpublic static <T> T doPrivileged(PrivilegedExceptionAction<T> action, AccessControlContext context, Permission... perms) throws PrivilegedActionException 指定されたAccessControlContextによって許可および制限される特権と、指定されたPermission引数によって制限される特権範囲を使用して、指定されたPrivilegedExceptionActionを実行します。 アクションは、呼出し側の保護領域で所有しているアクセス権と、指定されたAccessControlContextによって表される領域で所有しているアクセス権の共通部分を使って実行されます。アクションの runメソッドが(非チェック)例外をスローすると、例外はこのメソッドを使って送られます。セキュリティ・マネージャがインストールされ、指定された AccessControlContextがシステム・コードによって作成されず、呼出し元のProtectionDomainに「createAccessControlContext」SecurityPermissionが付与されていない場合、そのアクションはアクセス権なしで実行されます。- 型パラメータ:
- T- PrivilegedExceptionActionの- runメソッドによって返される値の型。
- パラメータ:
- action- 実行されるアクション。
- context- 指定されたアクションの実行前に呼出し側のドメインの特権に適用される制限を表す、アクセス制御コンテキスト。 コンテキストが- nullの場合、追加の制限は適用されない。
- perms- 呼出し元の特権のスコープを制限する- Permission引数。 引数の数は変動する。
- 戻り値:
- アクションのrunメソッドによって返される値。
- 例外:
- PrivilegedActionException- 指定されたアクションの- runメソッドがチェック例外をスローした場合
- NullPointerException- action、permsまたはpermsのいずれかの要素が- nullである場合
- 導入されたバージョン:
- 1.8
- 関連項目:
- doPrivileged(PrivilegedAction),- doPrivileged(PrivilegedAction,AccessControlContext)
 
 - 
doPrivilegedWithCombinerpublic static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action, AccessControlContext context, Permission... perms) throws PrivilegedActionException 指定されたAccessControlContextによって許可および制限される特権と、指定されたPermission引数によって制限される特権範囲を使用して、指定されたPrivilegedExceptionActionを実行します。 アクションは、呼出し側の保護領域で所有しているアクセス権と、指定されたAccessControlContextによって表される領域で所有しているアクセス権の共通部分を使って実行されます。アクションの runメソッドが(非チェック)例外をスローすると、例外はこのメソッドを使って送られます。このメソッドは、アクションの実行中、現在のAccessControlContextのDomainCombiner (nullの場合もある)を保存します。 セキュリティ・マネージャがインストールされ、指定された AccessControlContextがシステム・コードによって作成されず、呼出し元のProtectionDomainに「createAccessControlContext」SecurityPermissionが付与されていない場合、そのアクションはアクセス権なしで実行されます。- 型パラメータ:
- T- PrivilegedExceptionActionの- runメソッドによって返される値の型。
- パラメータ:
- action- 実行されるアクション。
- context- 指定されたアクションの実行前に呼出し側のドメインの特権に適用される制限を表す、アクセス制御コンテキスト。 コンテキストが- nullの場合、追加の制限は適用されない。
- perms- 呼出し元の特権のスコープを制限する- Permission引数。 引数の数は変動する。
- 戻り値:
- アクションのrunメソッドによって返される値。
- 例外:
- PrivilegedActionException- 指定されたアクションの- runメソッドがチェック例外をスローした場合
- NullPointerException- action、permsまたはpermsのいずれかの要素が- nullである場合
- 導入されたバージョン:
- 1.8
- 関連項目:
- doPrivileged(PrivilegedAction),- doPrivileged(PrivilegedAction,AccessControlContext),- DomainCombiner
 
 - 
getContextpublic static AccessControlContext getContext() このメソッドは、現在のスレッドの継承されたAccessControlContextと制限された特権スコープを含む、現在の呼出し側コンテキストの「スナップショット」を取得し、それをAccessControlContextオブジェクトに配置します。 このコンテキストは、あとで別のスレッドなどで検査される場合があります。- 戻り値:
- 現在のコンテキストに基づくAccessControlContext
- 関連項目:
- AccessControlContext
 
 - 
checkPermissionpublic static void checkPermission(Permission perm) throws AccessControlException 現在のAccessControlContextとセキュリティ・ポリシーに基づいて、指定されたアクセス権によって示されるアクセス要求が許可されるか拒否されるかを決定します。 このメソッドは、アクセス要求が許可される場合には何もしないで復帰し、そうでない場合にはAccessControlExceptionをスローします。 AccessControlExceptionのgetPermissionメソッドは、permPermissionオブジェクト・インスタンスを返します。- パラメータ:
- perm- 要求されたアクセス権。
- 例外:
- AccessControlException- 現在のセキュリティ・ポリシーに基づいて、指定されたアクセス権が許可されない場合。
- NullPointerException- 指定されたアクセス権が- nullであり、そのアクセス権が現在有効なセキュリティ・ポリシーに基づいてチェックされた場合。
 
 
- 
 
-