public int initSecContext(InputStream inStream, OutputStream outStream) throws GSSException {

    if (mechCtxt != null && currentState != IN_PROGRESS) {
      throw new GSSExceptionImpl(GSSException.FAILURE, "Illegal call to initSecContext");
    }

    GSSHeader gssHeader = null;
    int inTokenLen = -1;
    GSSCredentialSpi credElement = null;
    boolean firstToken = false;

    try {
      if (mechCtxt == null) {
        if (myCred != null) {
          try {
            credElement = myCred.getElement(mechOid, true);
          } catch (GSSException ge) {
            if (GSSUtil.isSpNegoMech(mechOid) && ge.getMajor() == GSSException.NO_CRED) {
              credElement = myCred.getElement(myCred.getMechs()[0], true);
            } else {
              throw ge;
            }
          }
        }
        GSSNameSpi nameElement = targName.getElement(mechOid);
        mechCtxt = gssManager.getMechanismContext(nameElement, credElement, reqLifetime, mechOid);
        mechCtxt.requestConf(reqConfState);
        mechCtxt.requestInteg(reqIntegState);
        mechCtxt.requestCredDeleg(reqCredDelegState);
        mechCtxt.requestMutualAuth(reqMutualAuthState);
        mechCtxt.requestReplayDet(reqReplayDetState);
        mechCtxt.requestSequenceDet(reqSequenceDetState);
        mechCtxt.requestAnonymity(reqAnonState);
        mechCtxt.setChannelBinding(channelBindings);
        mechCtxt.requestDelegPolicy(reqDelegPolicyState);

        objId = new ObjectIdentifier(mechOid.toString());

        currentState = IN_PROGRESS;
        firstToken = true;
      } else {
        if (mechCtxt.getProvider().getName().equals("SunNativeGSS")
            || GSSUtil.isSpNegoMech(mechOid)) {
          // do not parse GSS header for native provider or SPNEGO
          // mech
        } else {
          // parse GSS header
          gssHeader = new GSSHeader(inStream);
          if (!gssHeader.getOid().equals((Object) objId))
            throw new GSSExceptionImpl(
                GSSException.DEFECTIVE_TOKEN,
                "Mechanism not equal to " + mechOid.toString() + " in initSecContext token");
          inTokenLen = gssHeader.getMechTokenLength();
        }
      }

      byte[] obuf = mechCtxt.initSecContext(inStream, inTokenLen);

      int retVal = 0;

      if (obuf != null) {
        retVal = obuf.length;
        if (mechCtxt.getProvider().getName().equals("SunNativeGSS")
            || (!firstToken && GSSUtil.isSpNegoMech(mechOid))) {
          // do not add GSS header for native provider or SPNEGO
          // except for the first SPNEGO token
        } else {
          // add GSS header
          gssHeader = new GSSHeader(objId, obuf.length);
          retVal += gssHeader.encode(outStream);
        }
        outStream.write(obuf);
      }

      if (mechCtxt.isEstablished()) currentState = READY;

      return retVal;

    } catch (IOException e) {
      throw new GSSExceptionImpl(GSSException.DEFECTIVE_TOKEN, e.getMessage());
    }
  }
  public void acceptSecContext(InputStream inStream, OutputStream outStream) throws GSSException {

    if (mechCtxt != null && currentState != IN_PROGRESS) {
      throw new GSSExceptionImpl(GSSException.FAILURE, "Illegal call to acceptSecContext");
    }

    GSSHeader gssHeader = null;
    int inTokenLen = -1;
    GSSCredentialSpi credElement = null;

    try {
      if (mechCtxt == null) {
        // mechOid will be null for an acceptor's context
        gssHeader = new GSSHeader(inStream);
        inTokenLen = gssHeader.getMechTokenLength();

        /*
         * Convert ObjectIdentifier to Oid
         */
        objId = gssHeader.getOid();
        mechOid = new Oid(objId.toString());
        // System.out.println("Entered GSSContextImpl.acceptSecContext"
        //                      + " with mechanism = " + mechOid);
        if (myCred != null) {
          credElement = myCred.getElement(mechOid, false);
        }

        mechCtxt = gssManager.getMechanismContext(credElement, mechOid);
        mechCtxt.setChannelBinding(channelBindings);

        currentState = IN_PROGRESS;
      } else {
        if (mechCtxt.getProvider().getName().equals("SunNativeGSS")
            || (GSSUtil.isSpNegoMech(mechOid))) {
          // do not parse GSS header for native provider and SPNEGO
        } else {
          // parse GSS Header
          gssHeader = new GSSHeader(inStream);
          if (!gssHeader.getOid().equals((Object) objId))
            throw new GSSExceptionImpl(
                GSSException.DEFECTIVE_TOKEN,
                "Mechanism not equal to " + mechOid.toString() + " in acceptSecContext token");
          inTokenLen = gssHeader.getMechTokenLength();
        }
      }

      byte[] obuf = mechCtxt.acceptSecContext(inStream, inTokenLen);

      if (obuf != null) {
        int retVal = obuf.length;
        if (mechCtxt.getProvider().getName().equals("SunNativeGSS")
            || (GSSUtil.isSpNegoMech(mechOid))) {
          // do not add GSS header for native provider and SPNEGO
        } else {
          // add GSS header
          gssHeader = new GSSHeader(objId, obuf.length);
          retVal += gssHeader.encode(outStream);
        }
        outStream.write(obuf);
      }

      if (mechCtxt.isEstablished()) {
        currentState = READY;
      }
    } catch (IOException e) {
      throw new GSSExceptionImpl(GSSException.DEFECTIVE_TOKEN, e.getMessage());
    }
  }
 /**
  * Creates a GSSContextImpl out of a previously exported GSSContext.
  *
  * @see #isTransferable
  */
 public GSSContextImpl(GSSManagerImpl gssManager, byte[] interProcessToken) throws GSSException {
   this.gssManager = gssManager;
   mechCtxt = gssManager.getMechanismContext(interProcessToken);
   initiator = mechCtxt.isInitiator();
   this.mechOid = mechCtxt.getMech();
 }