text:
Queer Issue 2018 Jun 20, 2018
The Lesbian Who Taught Me What My Problem Was
I thought I hated my teacher. Turns out, I hated myself.
by Katie Herzog
"Is this what happens when you don't get any dick?" I'd joke about her, while turning up the volume on my Melissa Etheridge CD. "God. What a dyke." CURTIS BATHURST
It was my first semester of college at a small state university for people who didn't get into their top choice. I wasn't particularly interested in school, but I was even less interested in making a career for myself as a bagger down at the local Walmart. At least until I met the woman who would be my creative-writing professor. She made being a Walmart bagger seem like a fine option.
My teacher, who I'll call Sandy, wore too-big sweaters, dowdy leather clogs, and no makeup. She looked, most mornings, like she'd picked out her outfit from a pile on her floor. Worse, she usually had a Jeanette Winterson paperback tucked under one arm. She was the first openly gay woman I'd ever met. It may seem unbelievable that I could reach legal adulthood never having met a lesbian, but I'd grown up in a town with a population of less than 3,000 just over the hill from where Deliverance was filmed. Most of the women in my holler would never admit to an attraction to anyone outside their husbands, except maybe for Jesus and Dale Earnhardt.
Until college, the only time I heard the term "lesbian" was when it was in the form of a question. "Hey, you a lesbian?" I'd hear boys sneer in gym class before I looked around and realized that I was the one they were asking.
I never understood this, why I, of all people, was so falsely and unfairly pegged as gay. Sure, I had a bowl cut and was completely uninterested in boys, but this was 1996. Why would you be into boys when women's soccer was finally in the Olympics? I mean, sure, I might have occasionally had feelings about women, but that was normal. Everyone has crushes on their girlfriends—right?
Stereotypes are dangerous, but sometimes they are also true, and Sandy had "dyke" written all over her face. Besides, her sexuality was written into our course syllabus. Our reading list was entirely women who slept with women or looked like they did, from Virginia Woolf to Dorothy Allison, from Leslie Feinberg to Judith Butler. I was appalled by the whole thing, but especially by my teacher, who I was sure spent all of her nights home alone petting her 45 cats.
I never attempted to hide my disdain. I strolled in late and plopped down in the front row, and I slept in class more often than not. I wasn't interested in anything my teacher had to say, and when she gave me feedback on my writing—especially the feedback that essays required transitions between paragraphs and I needed to start using them—I'd say, "I don't believe in transitions," and leave in a huff.
Back in my dorm, I'd say to my roommate, "Is this what happens when you don't get any dick?" while turning up the volume on my Melissa Etheridge CD. "God. What a dyke."
At the end of the year, I dropped out of college for the first of many occasions and started working at a cafe where everyone else—everyone but me—was gay. They'd hired me, I later found out, because they assumed I was one of them. I was not, of course; I was a proud heterosexual. But these lesbians were cool. They were young and hip and had shaved heads and sculpted eyebrows. They weren't lonely. They didn't have cats.
Lesbians, I realized, could be this. Three months later, I was dating a woman.
Those years were the lesbian heyday. Queerness was still somewhat taboo, so when we found each other in small towns or big cities, we really connected. These days, if you nodded to every queer person you saw on the street, it would look like you have a tic—but in those days, when you saw dykes on the street, you made eye contact. You acknowledged them. These were the L Word years, and on Sunday evenings we would gather in the home of the one friend of a friend who had Showtime and watch The L Word in rapt silence, shushing each other if anyone dared to interrupt.
These were my people, I realized—the dykes, homos, and lezzies. And that teacher I'd hated? The one I'd made fun of and called a dyke? She was my people, too.
My wages at the lesbian cafe barely covered my rent, and I'd taken to dumpster diving to supplement my meager caloric intake. So, after a year, I went back to the college and, with no other options, enrolled in Sandy's class once again. I just hoped she wouldn't remember what an ass I'd been.
She did remember, but we never talked about our past, and we gradually came around to something like peace. Or, rather, I stopped being a dick, and she was gracious and professional enough not to hold it against me.
Years later, after I'd graduated from college, moved back and forth across the country three times, and finally started writing full-time, Sandy e-mailed me out of the blue. She had a book coming out, and it included a section about a student who'd almost driven her to quit teaching. The student's name, oddly enough, was "Katie," and she compared this Katie to an abusive ex-girlfriend. If I squinted hard enough, I could see the resemblance.
When her book tour came to Seattle, I went, and I bought a book. Later, alone, reading a chapter about myself, I clearly saw how terrible I had been. But I also knew by then that it had nothing to do with her and everything to do with me.
That teacher didn't teach me how to be gay—a group of radical lesbian baristas and my first girlfriend did that. But she taught me a lesson that has served me well over the years: Sometimes the thing that you hate most in other people is the thing you fear most in yourself. That, and the need for transitions.
• This piece appears in the 2018 Queer Issue as "That One Teacher." See also: "That One Serial Killer" by Dan Savage, "That One Drag Queen" by Jinkx Monsoon, "That One DJ" by Charles Mudede, "That One Writer" by Sophia Stephens, "That One Coworker" by Trisha Ready, "That One Parent" by Jing Jing Wang, "That One Roommate" by Christopher Frizzelle, "That One Radical Faerie" by Marc Castillo, "That One Songwriter" by Eli Sanders, "That One Filmmaker" by Chase Burns, and "That One Spouse" by Natalie Wood.
Katie Herzog
Katie Herzog is a staff writer at The Stranger, where she covers and comments on media, politics, pop culture, social movements, weed, climate change, free speech, French bulldogs, gender, sex, emotional support animals, airlines, Amazon, Donald Trump, Twitter mobs, internet hoaxes, wildfires, orcas, bike shares, Alex Jones, lesbians, the cost of living, conspiracy theories, moral panics, natural disasters, cults, the left, the right, the middle, podcasts, Jordan Peterson, Fox News, and, occasionally, Seattle.
Follow Email More articles
So Long... For Now
After Governor Bans Public Gatherings, Puget Sound Sports Are Canceled or Postponed
Why Weed and Alcohol Don't Mix
The scientific explanation for getting the spins.


Carrier Commercial Refrigeration has been awarded the Czech Business Superbrands Status in the commercial refrigeration category. Recognized worldwide, the Superbrands Status is given to the most outstanding brands in their respective fields. Superbrands, the world's largest independent arbiter of branding, operates in 88 countries, across five continents, focused on identifying and showcasing exceptional brands throughout the world. It has been operational in the Czech Republic since 2013.
Superbrands are identified annually through an extensive and robust research process that measures the equity of both direct-to-consumer and business-to-business brands. Superbrands nominees are initially selected based on business data and results, and narrowed down based on customer research. The final decision is made by the Superbrands Council, an independent committee comprised of marketing experts and business leaders in the local country.
CCR will be showcased in the Superbrands 2018 Yearbook with an article highlighting Carrier's history, innovation, brand value, achievements and social responsibility. The book will be issued in September. Carrier will also begin using the "Superbrands Award Seal" to symbolize its Superbrands Status in advertising and marketing materials within the Czech Republic.


text:
// Copyright 2015 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.android.ziputils;

import static com.google.devtools.build.android.ziputils.DataDescriptor.EXTLEN;
import static com.google.devtools.build.android.ziputils.DataDescriptor.EXTSIZ;
import static com.google.devtools.build.android.ziputils.DirectoryEntry.CENLEN;
import static com.google.devtools.build.android.ziputils.DirectoryEntry.CENOFF;
import static com.google.devtools.build.android.ziputils.DirectoryEntry.CENSIZ;
import static com.google.devtools.build.android.ziputils.EndOfCentralDirectory.ENDOFF;
import static com.google.devtools.build.android.ziputils.EndOfCentralDirectory.ENDSUB;

import com.google.common.primitives.UnsignedInts;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.FileChannel;
import java.util.Map;

/**
 * API for reading a zip file. This does not perform decompression of entry data, but provides
 * a raw view of the content of a zip archive.
 */
public class ZipIn {

  private static final byte[] EOCD_SIG = {0x50, 0x4b, 0x05, 0x06};
  private static final byte[] HEADER_SIG = {0x50, 0x4b, 0x03, 0x04};
  private static final byte[] DATA_DESC_SIG = {0x50, 0x4b, 0x07, 0x08};

  /**
   * Max end-of-central-directory size, including variable length file comment..
   */
  private static final int MAX_EOCD_SIZE = 1024;

  /**
   * Max local file header size, including long filename.
   */
  private static final int MAX_HEADER_SIZE = 64 * 1024;

  /**
   * Default size of direct byte buffer used for reading content. Actual allocation will not
   * exceed the archive content size, and may be at least as big as the largest entry.
   */
  private static final int READ_BLOCK_SIZE = 20 * 1024 * 1024;

  private final String filename; // filename or nickname.
  private final FileChannel fileChannel; // input file.
  private BufferedFile bufferedFile;
  private CentralDirectory cdir = null;
  private EndOfCentralDirectory eocd = null;
  private final boolean useDirectory;
  private final boolean ignoreDeleted;
  private final boolean verbose = false;

  /**
   * Creates a {@code ZipIn} view of a file, with a (nick)name.
   *
   * @param channel File channel open for reading.
   * @param filename filename or nickname.
   */
  public ZipIn(FileChannel channel, String filename) {
    this.fileChannel = channel;
    this.filename = filename;
    this.useDirectory = true;
    this.ignoreDeleted = useDirectory;
  }

  /**
   * Gets the file name for this zip input file.
   * @return the filename set at time of construction.
   */
  public String getFilename() {
    return filename;
  }

  /**
   * Returns a view of the "end of central directory" record expected at (or towards) the end of a
   * zip file.
   *
   * @return A read-only, {@link EndOfCentralDirectory}.
   * @throws IOException
   */
  public EndOfCentralDirectory endOfCentralDirectory() throws IOException {
    if (eocd == null) {
      loadEndOfCentralDirectory();
    }
    return eocd;
  }

  /**
   * Returns a memory mapped view of the central directory.
   *
   * @return A read-only, {@link CentralDirectory} of the central directory.
   * @throws IOException
   */
  public CentralDirectory centralDirectory() throws IOException {
    if (cdir == null) {
      loadCentralDirectory();
    }
    return cdir;
  }

  /**
   * Scans all entries in the zip file and invokes the given {@link EntryHandler} on each.
   *
   * @param handler handler to invoke for each file entry.
   * @throws IOException
   */
  public void scanEntries(EntryHandler handler) throws IOException {
    centralDirectory();
    ZipEntry zipEntry = nextFrom(null);
    while (zipEntry.getCode() != ZipEntry.Status.ENTRY_NOT_FOUND) {
      if (zipEntry.getCode() != ZipEntry.Status.ENTRY_OK) {
        throw new IOException(zipEntry.getCode().toString());
      }
      handler.handle(this, zipEntry.getHeader(), zipEntry.getDirEntry(), zipEntry.getContent());
      if (useDirectory && ignoreDeleted) {
        zipEntry = ZipIn.this.nextFrom(zipEntry.getDirEntry());
      } else {
        zipEntry = nextFrom(zipEntry.limit());
      }
    }
  }

  /**
   * Finds the next header, by scanning for a local header signature starting
   * at {@code offset}. This method will find headers for deleted or updated entries that
   * are not listed in the central directory, and may pickup false positive (e.g. entries
   * of an embedded zip file stored without compression). This method is primarily intended
   * for applications trying to recover data from corrupt archives.
   *
   * @param offset offset where to start the search.
   * @return the next local header at or beyond {@code offset}, or {@code null} if no
   * header is found.
   * @throws IOException
   */
  public LocalFileHeader nextHeaderFrom(long offset) throws IOException {
    int skipped = 0;
    for (ByteBuffer buffer = getData(offset + skipped, MAX_HEADER_SIZE);
        buffer.limit() >= LocalFileHeader.SIZE;
        buffer = getData(offset + skipped, MAX_HEADER_SIZE)) {
      int markerOffset = ScanUtil.scanTo(HEADER_SIG, buffer);
      if (markerOffset < 0) {
        skipped += buffer.limit() - 3;
      } else {
        skipped += markerOffset;
        LocalFileHeader header =  markerOffset == 0 ? localHeaderIn(buffer, offset + skipped)
            : localHeaderAt(offset + skipped);
        if (header != null) {
          if (skipped > 0) {
            System.out.println("Warning: local header search: skipped " + skipped + " bytes");
          }
          return header;
        }
        // If localHeaderIn or localHeaderAt decided it is not a header location,
        // we continue the search.
        skipped += 4;
      }
    }
    return null;
  }

  /**
   * Finds the header at the next higher offset listed in the central directory as containing
   * a local file header, starting from the offset of the given {@code dirEntry}. This method will
   * bypass any deleted or updated entries not listed in the directory, and also any entries from
   * embedded zip files, or random instance of the header signature. This is the preferred method
   * for sequentially reading the entries of a valid zip file.
   *
   * @param dirEntry directory entry for the "current entry", providing the start point
   * for searching the central directory for the entry with the next higher offset.
   * @return the next header according to the central directory, or {@code null} if there are no
   * more headers.
   * @throws IOException
   */
  public LocalFileHeader nextHeaderFrom(DirectoryEntry dirEntry) throws IOException {
    Long nextOffset = dirEntry == null ? -1 : dirEntry.get(CENOFF);
    while ((nextOffset = cdir.mapByOffset().higherKey(nextOffset)) != null) {
      LocalFileHeader header = localHeaderAt(nextOffset);
      if (header != null) {
        return header;
      }
      System.out.println("Warning: no header for file listed in directory "
          + dirEntry.getFilename());
      // The file is corrupt! Continue to see how bad it is.
    }
    return null;
  }

  /**
   * Provides a {@code LocalFileHeader} view of a local header located at the offset indicated
   * by the given {@code dirEntry}.
   *
   * @param dirEntry the directory entry referring to the headers location.
   * @return the requested header, or {@code null} if the given location can't possibly contain a
   * valid file header (e.g. missing header signature), or if {@code dirEntry} is {@code null}.
   * @throws IOException
   */
  public LocalFileHeader localHeaderFor(DirectoryEntry dirEntry) throws IOException {
    return dirEntry == null ? null : localHeaderAt(dirEntry.get(CENOFF));
  }

  /**
   * Provides a {@code LocalFileHeader} view of a local header located at the offset indicated by
   * the given {@code dirEntry}.
   *
   * @param offset offset at which header is presumed to exist.
   * @return the requested header, or {@code null} if the given location can't possibly contain a
   *     valid file header (e.g. missing header signature).
   * @throws IOException
   */
  public LocalFileHeader localHeaderAt(long offset) throws IOException {
    return localHeaderIn(getData(offset, MAX_HEADER_SIZE), offset);
  }

  /**
   * Finds the next zip file entry, by scanning for a local header using the
   * {@link #nextHeaderFrom(long) }method.
   *
   * @param offset offset where to start the search.
   * @return a {@code ZipEntry} object with the result of the search.
   * @throws IOException
   */
  public ZipEntry nextFrom(long offset) throws IOException {
    LocalFileHeader header = ZipIn.this.nextHeaderFrom(offset);
    return entryWith(header);
  }

  /**
   * Finds the next zip file entry, by first invoking
   * {@link #nextHeaderFrom(com.google.devtools.build.android.ziputils.DirectoryEntry) }
   * to find its header.
   *
   * @param entry the directory entry for the "current" zip entry, or {@code null} to get
   * the first entry.
   * @return a {@code ZipEntry} object with the result of the search.
   * @throws IOException
   */
  public ZipEntry nextFrom(DirectoryEntry entry) throws IOException {
    long offset = entry == null ? -1 : entry.get(CENOFF);
    Map.Entry<Long, DirectoryEntry> mapEntry = cdir.mapByOffset().higherEntry(offset);
    if (mapEntry == null) {
      return entryWith(null);
    }
    LocalFileHeader header = localHeaderAt(mapEntry.getKey());
    return entryWith(header, mapEntry.getValue());
  }

  /**
   * Finds the zip file entry, for a given directory entry.
   *
   * @param entry the directory entry for which a zip entry is requested.
   * @return a {@code ZipEntry} object with the result of the search.
   * @throws IOException
   */
  public ZipEntry entryFor(DirectoryEntry entry) throws IOException {
    return entryWith(localHeaderFor(entry), entry);
  }

  /**
   * Returns the zip file entry at the given offset.
   *
   * @param offset presumed location of local file header.
   * @return a {@link ZipEntry} for the given location.
   * @throws IOException
   */
  public ZipEntry entryAt(long offset) throws IOException {
    LocalFileHeader header = localHeaderAt(offset);
    return entryWith(header);
  }

  /**
   * Constructs a {@link ZipEntry} view of the entry at the location of the given header.
   *
   * @param header a previously located header. If (@code useDirectory} is set, this will attempt to
   *     lookup a corresponding directory entry. If there is none, and {@code ignoreDeleted} is also
   *     set, the return value will flag this entry with a {@code ZipEntry.Status.ENTRY_NOT_FOUND}
   *     status code.
   * @return {@link ZipEntry} for the given location.
   * @throws IOException
   */
  public ZipEntry entryWith(LocalFileHeader header) throws IOException {
    if (header == null) {
      return new ZipEntry().withCode(ZipEntry.Status.ENTRY_NOT_FOUND);
    }
    // header != null
    long offset = header.fileOffset();
    DirectoryEntry dirEntry = null;
    if (useDirectory) {
      dirEntry = cdir.mapByOffset().get(offset);
      if (dirEntry == null && ignoreDeleted) {
        return new ZipEntry().withCode(ZipEntry.Status.ENTRY_DELETED);
      }
    }
    return entryWith(header, dirEntry);
  }

  /**
   * Constructs a zip entry object for the location of the given header, with the corresponding
   * directory entry.
   *
   * @param header local file header for the entry.
   * @param dirEntry corresponding directory entry, or {@code null} if not available.
   * @return a zip entry with the given header and directory entry.
   * @throws IOException
   */
  private ZipEntry entryWith(LocalFileHeader header, DirectoryEntry dirEntry) throws IOException {
    ZipEntry zipEntry = new ZipEntry().withHeader(header).withEntry(dirEntry);
    long offset = header.fileOffset() + header.getSize();
    // !useDirectory || dirEntry != null || !ignoreDeleted
    String entryName = header.getFilename();
    if (dirEntry != null && !entryName.equals(dirEntry.getFilename())) {
      return zipEntry.withEntry(dirEntry).withCode(ZipEntry.Status.FILENAME_ERROR);
    }
    long sizeByHeader = header.dataSize();
    long sizeByDir = dirEntry != null ? dirEntry.dataSize() : -1;
    ByteBuffer content;
    if (sizeByDir == sizeByHeader && sizeByDir >= 0) {
      // Ideal case, header and directory in agreement
      content = getData(offset, sizeByHeader);
      if (content.limit() == sizeByHeader) {
        return zipEntry.withContent(content).withCode(ZipEntry.Status.ENTRY_OK);
      } else {
        return zipEntry.withContent(content).withCode(ZipEntry.Status.NOT_ENOUGH_DATA);
      }
    }
    if (sizeByDir >= 0) {
      // If file is correct, we get here because of a 0x8 flag, and we expect
      // data to be followed by a data descriptor.
      content = getData(offset, sizeByDir);
      DataDescriptor dataDesc = descriptorAt(offset + sizeByDir, dirEntry);
      if (dataDesc != null) {
        return zipEntry
            .withContent(content)
            .withDescriptor(dataDesc)
            .withCode(ZipEntry.Status.ENTRY_OK);
      }
      return zipEntry.withContent(content).withCode(ZipEntry.Status.NO_DATA_DESC);
    }
    if (!ignoreDeleted) {
      if (sizeByHeader >= 0) {
        content = getData(offset, sizeByHeader);
        if (content.limit() == sizeByHeader) {
          return zipEntry.withContent(content).withCode(ZipEntry.Status.ENTRY_OK);
        }
        return zipEntry.withContent(content).withCode(ZipEntry.Status.NOT_ENOUGH_DATA);
      } else {

        DataDescriptor dataDesc = descriptorFrom(offset, dirEntry);
        if (dataDesc == null) {
          // Only way now would be to decompress
          return zipEntry.withCode(ZipEntry.Status.UNKNOWN_SIZE);
        }
        long sizeByDesc = dataDesc.get(EXTSIZ);
        if (sizeByDesc != dataDesc.fileOffset() - offset) {
          // That just can't be the right
          return zipEntry.withDescriptor(dataDesc).withCode(ZipEntry.Status.UNKNOWN_SIZE);
        }
        content = getData(offset, sizeByDesc);
        return zipEntry
            .withContent(content)
            .withDescriptor(dataDesc)
            .withCode(ZipEntry.Status.ENTRY_OK);
      }
    }
    return zipEntry.withCode(ZipEntry.Status.UNKNOWN_SIZE);
  }

  /**
   * Scans for a data descriptor from a given offset.
   *
   * @param offset position where to start the search.
   * @param dirEntry directory entry for validation, or {@code null}.
   * @return A data descriptor view for the next position containing the data descriptor signature.
   * @throws IOException
   */
  public DataDescriptor descriptorFrom(final long offset, final DirectoryEntry dirEntry)
      throws IOException {
    int skipped = 0;
    for (ByteBuffer buffer = getData(offset + skipped, MAX_HEADER_SIZE);
        buffer.limit() >= 16; buffer = getData(offset + skipped, MAX_HEADER_SIZE)) {
      int markerOffset = ScanUtil.scanTo(DATA_DESC_SIG, buffer);
      if (markerOffset < 0) {
        skipped += buffer.limit() - 3;
      } else {
        skipped += markerOffset;
        return markerOffset == 0 ? descriptorIn(buffer, offset + skipped, dirEntry)
            : descriptorAt(offset + skipped, dirEntry);
      }
    }
    return null;
  }

  /**
   * Creates a data descriptor view at a given offset.
   *
   * @param offset presumed location of data descriptor.
   * @param dirEntry directory entry to use for validation, or {@code null}.
   * @return a data descriptor view over the given file offset.
   * @throws IOException
   */
  public DataDescriptor descriptorAt(long offset, DirectoryEntry dirEntry) throws IOException {
    return descriptorIn(getData(offset, 16), offset, dirEntry);
  }

  /**
   * Constructs a local header view over a give byte buffer.
   *
   * @param buffer byte buffer with local header data.
   * @param offset file offset at which the buffer is based.
   * @return a local header view.
   */
  private LocalFileHeader localHeaderIn(ByteBuffer buffer, long offset) {
    return buffer.limit() < LocalFileHeader.SIZE
        || buffer.getInt(0) != LocalFileHeader.SIGNATURE
        ? null : LocalFileHeader.viewOf(buffer).at(offset);
  }

  /**
   * Constructs a data descriptor view over a given byte buffer.
   *
   * @param buf byte buffer with data descriptor data.
   * @param offset file offset at which the buffer is based.
   * @param dirEntry directory entry with presumed reliable content size information.
   * @return a data descriptor
   */
  private DataDescriptor descriptorIn(ByteBuffer buf, long offset, DirectoryEntry dirEntry) {
    if (buf.limit() < 12) {
      return null;
    }
    DataDescriptor desc = DataDescriptor.viewOf(buf).at(offset);
    if (desc.hasMarker() || (dirEntry != null
        && desc.get(EXTSIZ) == dirEntry.get(CENSIZ)
        && desc.get(EXTLEN) == dirEntry.get(CENLEN))) {
      return desc;
    }
    return null;
  }

  /** Obtains a byte buffer at a given offset. */
  private ByteBuffer getData(long offset, long size) throws IOException {
    return bufferedFile
        .getBuffer(offset, UnsignedInts.checkedCast(size))
        .order(ByteOrder.LITTLE_ENDIAN);
  }

  /**
   * Locates the "end of central directory" record, expected located at the end of the file, and
   * reads it into a byte buffer. Called on the first invocation of
   * {@link #endOfCentralDirectory() }.
   *
   * @throws IOException
   */
  protected void loadEndOfCentralDirectory() throws IOException {
    cdir = null;
    long size = fileChannel.size();
    verbose("Loading ZipIn: " + filename);
    verbose("-- size: " + size);
    int cap = (int) Math.min(size, MAX_EOCD_SIZE);
    ByteBuffer buffer = ByteBuffer.allocate(cap).order(ByteOrder.LITTLE_ENDIAN);
    long offset = size - cap;
    while (true) {
      fileChannel.position(offset);
      while (buffer.hasRemaining()) {
        fileChannel.read(buffer, offset);
      }
      // scan to find it...
      int endOfDirOffset = ScanUtil.scanBackwardsTo(EOCD_SIG, buffer);
      if (endOfDirOffset < 0) {
        if (offset == 0) {
          if (useDirectory) {
            throw new IllegalStateException("No end of central directory marker");
          } else {
            break;
          }
        }
        offset = Math.max(offset - 1000, 0);
        buffer.clear();
        continue;
      }
      long eocdFileOffset = offset + endOfDirOffset;
      verbose("-- EOCD: " + eocdFileOffset + " size: " + (size - eocdFileOffset));
      buffer.position(endOfDirOffset);
      eocd = EndOfCentralDirectory.viewOf(buffer).at(offset + endOfDirOffset);
      // TODO (bazel-team): check that the end of central directory, points to a valid
      // first directory entry. If not, assume we happened to find the signature inside
      // a file comment, and resume the search.
      break;
    }

    if (eocd != null) {
      bufferedFile = new BufferedFile(fileChannel, 0, eocd.get(ENDOFF),
          READ_BLOCK_SIZE);
    } else {
      bufferedFile = new BufferedFile(fileChannel, READ_BLOCK_SIZE);
    }
  }

  /**
   * Maps the central directory to memory. Called on the first invocation of
   * {@link #centralDirectory() }.
   *
   * @throws IOException
   */
  protected void loadCentralDirectory() throws IOException {
    if (eocd == null) {
      loadEndOfCentralDirectory();
    }
    if (eocd == null) {
      return;
    }
    long cdOffset = eocd.get(ENDOFF);
    long len = eocd.fileOffset() - cdOffset;
    verbose("-- CDIR: " + cdOffset + " size: " + len + " count: " + eocd.get(ENDSUB));
    // Read directory to buffer.
    // TODO(bazel-team): we currently assume the directory fits in memory (and int).
    ByteBuffer buffer = ByteBuffer.allocateDirect((int) len);
    while (len > 0) {
      int read = fileChannel.read(buffer, cdOffset);
      len -= read;
      cdOffset += read;
    }
    buffer.rewind();
    cdir = CentralDirectory.viewOf(buffer).at(cdOffset).parse();
    cdir.buffer.flip();
  }

  /**
   * Zip file entry container class, for use with the low-level scanning operations of this
   * API, supporting zip file scanner construction.
   */
  public static class ZipEntry {

    private LocalFileHeader header;
    private DataDescriptor descriptor;
    private ByteBuffer content;
    private DirectoryEntry entry;
    private Status code;

    /**
     * Creates a zip entry, setting the initial status to not found.
     */
    public ZipEntry() {
      code = Status.ENTRY_NOT_FOUND;
    }

    /**
     * Gets the header of this zip entry.
     */
    public LocalFileHeader getHeader() {
      return header;
    }

    /**
     * Sets the header of this zip entry.
     *
     * @return this object.
     */
    @CanIgnoreReturnValue
    public ZipEntry withHeader(LocalFileHeader header) {
      this.header = header;
      return this;
    }

    /**
     * Gets the data descriptor of this zip entry, if any.
     */
    public DataDescriptor getDescriptor() {
      return descriptor;
    }

    /**
     * Sets the data descriptor of this zip entry.
     *
     * @return this object.
     */
    @CanIgnoreReturnValue
    public ZipEntry withDescriptor(DataDescriptor descriptor) {
      this.descriptor = descriptor;
      return this;
    }

    /**
     * Gets a byte buffer for accessing the raw content of this zip entry.
     */
    public ByteBuffer getContent() {
      return content;
    }

    /**
     * Sets the byte buffer providing access to the raw content of this zip entry.
     *
     * @return this object
     */
    @CanIgnoreReturnValue
    public ZipEntry withContent(ByteBuffer content) {
      this.content = content;
      return this;
    }

    /**
     * Gets the central directory entry for this zip entry, if any.
     */
    public DirectoryEntry getDirEntry() {
      return entry;
    }

    /**
     * Sets the central directory entry for this zip entry.
     *
     * @return this object.
     */
    @CanIgnoreReturnValue
    public ZipEntry withEntry(DirectoryEntry entry) {
      this.entry = entry;
      return this;
    }

    /**
     * Gets the status code for parsing this zip entry.
     */
    public Status getCode() {
      return code;
    }

    /**
     * Sets the status code for this zip entry.
     *
     * @return this object.
     */
    @CanIgnoreReturnValue
    public ZipEntry withCode(Status code) {
      this.code = code;
      return this;
    }

    /**
     * Calculates, best-effort, the file offset just past this zip entry.
     */
    public long limit() {
      if (header == null) {
        return 0;
      }
      if (descriptor != null) {
        return descriptor.fileOffset() + descriptor.getSize();
      }
      long offset = header.fileOffset() + header.dataSize();
      if (content != null) {
        offset += content.limit();
      }
      return offset;
    }

    /**
     * Zip entry parsing status codes.
     */
    public enum Status {
      /**
       * This zip entry contains valid header and data
       */
      ENTRY_OK,
      /**
       * No header at the given location
       */
      ENTRY_NOT_FOUND,
      /**
       * The given location contains a header that is not listed in the central directory
       */
      ENTRY_DELETED,
      /**
       * The header in the given location has a different filename than the
       * directory entry for this location.
       */
      FILENAME_ERROR,
      /**
       * The given location has the header signature, but the remaining data is insufficient
       * to constitute a complete entry.
       */
      NOT_ENOUGH_DATA,
      /**
       * The entry appears to be missing an expected data descriptor.
       */
      NO_DATA_DESC,
      /**
       * The implementation was unable to determine the size of the content of the entry.
       * The client will have to either parse using the central directory, or if all else
       * fails, attempt to decompress the entry.
       */
      UNKNOWN_SIZE,
    }
  }

  private void verbose(String msg) {
    if (verbose) {
      System.out.println(msg);
    }
  }
}

redpajama_set_name: RedPajamaGithub


This Church shall strive to proclaim and protect the whole counsel of God's Word, by proclaiming the true Gospel of Jesus Christ, by establishing and teaching sound doctrine, and by exhorting individuals and families to engage in and promote the personal study of God's Word, for through these means we guard the truth entrusted to us for this and following generations.
This Church desires to offer up to God the worship that He so richly deserves as our Creator, Savior, and Lord, humbly worshiping Him in spirit and truth with a desire to please Him.
The word of God prompts us to worship Him in many ways: praising Him in word and song, with instruments; through prayer and thanksgiving, through joyful giving, and through our loving obedience in all things.
An important part of our worship is keeping the two ordinances which Christ Jesus gave us: the baptism of believers as a testimony of salvation, and the celebration of the Lord's supper as a proclamation of the Lord's death until He comes again. In all these things we confess that God alone is worthy of our worship, and that we are to worship no other.
This Church is to build up and protect one another through discipline and training; meeting each other's physical, spiritual and emotional needs; meeting together regularly; avoiding and settling disputes; purifying itself by exercising discipline; and through praying for, encouraging , and loving one another.
This Church as a body of individuals, is to make disciples by teaching and exempting the Word of God so that believers grow in their love of Christ, in their obedience to His word, in their anticipation of His return, and in their ability and desire to proclaim His gospel. Those whom God saves we are to baptize and bring into the body so that they also may grow and make disciples.
This Church shall minister both spiritually and physically to fellow-believer and the strangers in our midst, as well as to the world-at-large, especially to widows, orphan, prisoners, the poor, and the sick. This Church must also be an example to the community, as demonstrated in our relationships with our families, employers and employees , as well as in our obedience to leaders in governments and in the Church.
The civil authority that God has appointed over us recognizes this Church as a legal entity subject to certain laws and regulations. One privilege we enjoy as a non-profit corporation is a tax-exempt status. At this time this privilege has no conditions that prevent us from carrying out the purposes of the Church.
This Church shall at all times be operated so as to be consistent with the requirements of 501(c)(3) of the Internal Revenue Code of 1954 and any regulations promulgated thereunder or the corresponding provisions of any subsequent federal tax laws. No part of net earnings, gains, profits or dividends shall inure to the benefit of, or be distributable to its members, deacons, officers, elders, or other private persons, except that reasonable compensation for services rendered, and to make payments and distributions in furtherance of the purposes set forth above. The private property of the incorporators, elders, and officers, shall not be subject to the payment of corporate debts to any extent whatever, in furtherance of and not in limitation of the powers conferred by statute; this Church is expressly authorized to on its business and to hold annual or special meetings of its Board of Elders in any of the states, territories or possessions of the United States, or the District of Columbia. Notwithstanding any other provision of these Bylaws, this Church shall not conduct or carry on any activities not permitted to be conducted or carried on by an organization exempt under 501(c)(3) of the Internal Revenue Code of 1954, or corresponding provisions of any subsequent federal tax laws.
In the event of dissolution of this Church, its assets remaining after payment, or provision of payment of all debts and liabilities of this Church, shall be distributed exclusively for religious purposes to one or more churches or organizations of like faith, which are then exempt from deferral tax under 501(c)(3) of the Internal Revenue Code of 1954, or corresponding provisions of any subsequent federal tax laws and to which contributions are then deductible under 170(c)(2) of such code or corresponding provisions of any subsequent federal tax laws.
Should there come a time when the conditions of maintaining our tax-exempt status would prevent us from carrying out the purposes of the Church, we must obey God rather than man, and, therefore, forfeit our tax-exempt status.


text:
8,000 agents marked in upcoming ATO program
Over 8,000 tax agents will be visited over the next four years as the ATO looks to ramp up its educational campaign to help agents who are under pressure and error-prone.
Tax&Compliance	Jotham Lian 13 September 2018
object(stdClass)#17970 (7) { ["image_intro"]=> string(54) "images/articleimages-391x261/850x492/ATO-form-1-ad.jpg" ["float_intro"]=> string(0) "" ["image_intro_alt"]=> string(29) "ato tax agents ato campaign" ["image_intro_caption"]=> string(0) "" ["image_fulltext"]=> string(0) "" ["image_fulltext_alt"]=> string(0) "" ["image_fulltext_caption"]=> string(0) "" }
13 Sep 2018 — 2 min read
Speaking on the ATO's tax professionals webcast, Assistant Commissioner Colin Walker said that 2,000 tax agents will be visited per year over the next four years as it tries to identify stressors causing errors contributing to the $8.76 billion individuals tax gap.
Mr Walker was keen to stress that these visits would be separate from its work on the 500 agents of concern who fail to go by the law.
The ATO had previously classified tax agents into three groups: one, those who are "examples of the profession" and have the right processes and checks in place; two, agents who are making "avoidable mistakes"; and lastly, a small number of 500 tax agents who fail to go by the law.
"We have a project that will see us do a lot of work with that group of agents that are trying to do the right thing but at times are indicating that they are having trouble or they are indicating they are making mistakes," said Mr Walker.
"[We will be] focusing on that group of agents that seem to have a little bit of strife, they are quite compliant in the normal circumstances and we are going to develop ways and means to try and help them to work through so they don't become agents who are egregious and don't become agents who are reckless and at the same time we are able to get a level playing field.
"[We want] to not only understand the difficulties and the stressors and the strains that the agents are going through but to [also] give them good advice as to how to deal with those issues. It is not about compliance; it is about helping people to get it right."
Level the playing field
Morris and Associates tax principal Mark Morris said that it was important to have more rigour in the tax system to provide a level playing field for model tax agents and to understand what was driving some agents to make mistakes.
"Is it because clients are increasingly discriminating in terms of fees, there's a lot more shopping around, so is that a factor? Is it a factor that you may not be able to get qualified staff to help you? Is it a factor that you end up giving advice on areas you perhaps shouldn't because you don't have the confidence, and I also think it is also a factor, with respect to government, the complexity of the legislation," said the professor of practice at La Trobe University.
"They debrand us. When they don't have integrity, then you get a sense the whole profession is affected."
Likewise, Anderson Tax and Consulting director Debra Anderson was hopeful that the ATO's program would help put a stop to certain poor practices in the industry.
"I think prevention is always better than cure," said Ms Anderson.
"The level playing field is very close to my heart. I've lost a few clients this year because I wouldn't claim the dining table and chairs, the $4,000 couch, the $10,000-a-month personal trainer which was put as staff training.
"There are so many good agents and they are really frustrated that there are this handful that aren't."

redpajama_set_name: RedPajamaCommonCrawl


JBoss EAP 7.0 quickstarts is a set of example applications demonstrating various aspects of JBoss EAP 7.0. In this post, similarly to the previous post on running Java EE 7 Samples, we'll examine how to run JBoss EAP 7.0 quickstarts with WildFly Swarm.
Again, it turns out it's pretty easy. In this text, we'll take a look at couple of quickstarts, how to build them, create a Swarm uberjar, and possibly run some tests.
But before we start, we need two things: the Swarmtool itself, and a clone of the JBoss EAP 7.0 quickstarts.
We see that each Swarm version has its own version of Swarmtool. The Swarmtool version 2017.4.0 will use Swarm 2017.4.0 to create the uberjar.
Note that the repository is fairly big.
Let's start with a very simple quickstart, the helloworld one. It contains a simple servlet which injects a CDI bean.
You'll see that Swarmtool autodetects the cdi and undertow fractions. The cdi fraction, obviously, provides CDI, and undertow provides an HTTP server and a servlet container.
And that's it! There's nothing more to this quickstart.
Now, let's follow with a quickstart that uses a database. Naturally, it will be the in-memory H2 database, but the steps to use a real database would be very similar.
Clearly, the H2 driver isn't present. If you consult the HOWTO, you will learn that it's enough to add a dependency on the JDBC driver.
The uberjar now starts just fine and you can open your browser at http://localhost:8080/ to play with the application.
Let's get to something more interesting. The ejb-security quickstart expects some users and roles to be defined in the application-users.properties and application-roles.properties files. Of course, we could create those files using WildFly / JBoss EAP 7.0 tools and then instruct Swarm to use them, but we'll go for a different solution today.
The preferred way of configuring Swarm applications is a YAML format. Can we create a project-defaults.yml file and embed the users/roles definition into it?
WildFly / JBoss EAP 7.0 provides solution for defining users directly inside definition of a security realm, but a solution for defining user roles as well is missing. Therefore, Swarm provides its own solution for defining both users and roles inside a definition of the security realm.
The plug-in-authorization part is probably clear; the user quickstartUser is in the role guest, and user1 is in the role app-user. But what about the first part, plug-in-authentication? What are the values?
In fact, the value is exactly the same as in the application-users.properties file. So if you already have this file and don't want to configure Swarm to use it, you can easily copy all the required pieces to a Swarm YAML file.
Notice the -f parameter, which specifies the management fraction. Without it, we couldn't define security realms.
Here, notice the -s parameter: the project-defaults.yml file doesn't exist in the original .war file; it lives on the filesystem outside of the uberjar.
It's 200 OK now. And the user1?
403 Forbidden, exactly as expected.
And last but not least, one quickstart that uses Arquillian for testing. Here, we'll use a lot of tricks we learned in the post on running Java EE 7 Samples.
Here just notice that a dependency on H2 is added, because the application uses a database.
Here, you should notice that we added a webdriver section which specifies that the Firefox browser will be used for running browser-based tests. This is copied from the existing arquillian.xml.
Another thing to notice here is that we're using Firefox 45 ESR. This is because newer versions of Firefox aren't compatible with the FirefoxDriver implementation brought in by Graphene WebDriver.
All these steps should be familiar, if you read the previous post on running Java EE 7 Samples.
There's a couple of generally useful things in this case study. Let's summarize them.
WildFly Swarm provides a standalone tool to generate uberjars from traditional .jar or .war deployment archives, the Swarmtool.
Swarmtool performs fraction autodetection, but it's possible to specify additional fractions and even additional Maven dependencies.
Swarmtool-produced archives can also use the Swarm YAML configuration. The YAML file doesn't have to be in the original .war, it can live on the filesystem just fine.
And finally, if you hit any issue with Swarmtool or generally with migrating applications from WildFly / JBoss EAP 7.0 to Swarm, please file an issue. Thanks!